Estoy tratando de pasar por el ejemplo YesNo
del libro Learn You a Haskell for Great Good!
.Variable de tipo ambiguo `a0 'en las restricciones
Aquí está mi código fuente:
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
Cuando ejecuto el código siguiente excepción se produce:
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))
¿Puede usted explicar lo que está mal con este código?
¿Es posible crear su propio tipo de constructores de datos que funcionan como '12' en Haskell? Parece que cada vez que creas un constructor de datos, construye un valor de un solo tipo. Pero cuando escribe '12', como puede ver, no construye un valor de un solo tipo, sino un valor de cualquier tipo donde el tipo está restringido por Num. Por lo tanto 'Num a => a'. ¿Estoy interpretando esto correctamente? ¿Esto es como construir un valor que tiene una unión existencial? – CMCDragonkai
@CMCDragonkai Estoy un poco confuso con los detalles, pero básicamente la clase de tipos 'Num' contiene una función' fromInteger :: Num a => Integer -> a'. Un literal numérico funciona como si se llamara 'fromInteger'. – fuz
Ah, entonces el 'a' se convierte en una especie de unión/existencial. Muy interesante. – CMCDragonkai