Próbuję przejrzeć przykład YesNo
z książki Learn You a Haskell for Great Good!
.Niejednoznaczna zmienna typu "a0" w ograniczeniach
Oto mój kod źródłowy:
module Main where
main :: IO()
main = putStrLn (show (yesno 12))
class YesNo a where
yesno :: a -> Bool
instance YesNo Bool where
yesno b = b
instance YesNo [a] where
yesno [] = False
yesno _ = True
instance YesNo Int where
yesno 0 = False
yesno _ = True
Kiedy wykonać ten kod pojawia się następujący wyjątek:
Ambiguous type variable `a0' in the constraints:
(YesNo a0) arising from a use of `yesno'
at /Users/mkhadikov/Projects/personal/haskell/hello-world/yesno.hs:5:25-29
(Num a0) arising from the literal `12'
at /Users/mkhadikov/Projects/personal/haskell/hello-world/yesno.hs:5:31-32
Probable fix: add a type signature that fixes these type variable(s)
In the first argument of `show', namely `(yesno 12)'
In the first argument of `putStrLn', namely `(show (yesno 12))'
In the expression: putStrLn (show (yesno 12))
Czy możesz wyjaśnić, co jest nie tak z tym kodem?
Czy to możliwe, aby stworzyć swój własny rodzaj konstruktorów danych, które działają podobnie jak '12' w Haskell? Wydaje się, że gdy tworzysz konstruktor danych, konstruuje on wartość jednego typu. Ale kiedy piszesz '12', jak widzisz, nie tworzy wartości jednego typu, ale wartość dowolnego typu, gdzie typ jest ograniczony przez Num. Tak więc "Num a => a". Czy interpretuję to poprawnie? Czy jest to podobne do konstruowania wartości, która ma egzystencjalne/związek? – CMCDragonkai
@CMCDragonkai Jestem trochę rozmyta na szczegóły, ale zasadniczo typeclass 'Num' zawiera funkcję' fromInteger :: Num a => Integer -> a'. Literał numeryczny działa tak, jakby został wywołany 'fromInteger'. – fuz
Ach, więc "a" w pewnym sensie staje się egzystencjalnym/związkowym. Bardzo interesujące. – CMCDragonkai