我正在尝试通过YesNo
示例来自Learn You a Haskell for Great Good!
book.
这是我的源代码:
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
当我执行此代码时,会发生以下异常:
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))
您能解释一下这段代码有什么问题吗?
问题是它不知道类型 12 是什么!有可能any使用 Num 实例键入:
GHCi> :t 12
12 :: Num a => a
你需要直接指定你想要的类型:tryputStrLn (show (yesno (12 :: Int)))
.
你可能会问,为什么 GHC 不能选择 Int,因为没有其他选择可以工作?好问题。答案是,使用 Haskell 的类型类系统,添加实例永远不会使现有的正确程序无效或改变它们的行为。 (这被称为开放世界假设.) 如果它确实选择了 Int,那么如果你添加了会发生什么instance YesNo Integer
?选择将变得不明确,并且您的程序将崩溃!
因此,当您想要将这样的类型类与多态值一起使用时,您必须更准确地指定您所指的类型。这在实践中应该不会出现太多,因为通常会有一些周围的上下文来强制类型成为您想要的类型;受此影响的主要是数字文字。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)