Следующий код предназначен для создания либо двойного, либо целочисленного. s
предполагается либо negate
, либо id
; n
вся деталь; и f
дробная часть или Nothing
для целого числа.Потеря полиморфизма после сопоставления с образцом
computeValue :: Num a => (a->a) -> Integer -> (Maybe Double) -> Either Double Integer
computeValue s n Nothing = Right $ s n
computeValue s n (Just a) = Left $ s (fromIntegral n + a)
, когда я скомпилировать это я получаю:
test1.hs:2:28:
Couldn't match type `Integer' with `Double'
Expected type: Either Double Integer
Actual type: Either Double a
In the expression: Right $ s n
In an equation for `computeValue':
computeValue s n Nothing = Right $ s n
test1.hs:2:38:
Couldn't match type `Integer' with `Double'
In the first argument of `s', namely `n'
In the second argument of `($)', namely `s n'
In the expression: Right $ s n
Похоже, так или иначе компилятор потерял след того факта, что s
является полиморфным. Что здесь произошло и как это исправить?
Интересно! Я нашел то, что было неправильно (он действительно хотел «Либо a'), как возвращение, но я не понимал, что вокруг есть способ. –
@leftaroundabout: На самом деле вам нужно _универсально_ количественно '' ', и это то, что делает подпись 2-го ранга. 'ExistentialQuantification' ничего не делает в этом примере, важным расширением является« Rank2Types ». – Vitus
@Vitus: ах, правильно! Я продолжаю смешивать его, но это имеет смысл, думая об этом. Ред. – leftaroundabout