我想在ghci
控制台中做一个最简单的事情。我希望能够拥有[Maybe Int]
类型的值。但是,Nothing : [1, Nothing]
或[1, Nothing] ++ [Nothing]
会出现我觉得难以理解的错误:
No instance for (Num (Maybe a0)) arising from a use of ‘it’
In the first argument of ‘print’, namely ‘it’
In a stmt of an interactive GHCi command: print it
可以请某人解释此错误并建议如何修复它吗?
答案 0 :(得分:7)
在Haskell中,列表(即某些[a]
类型为a
的内容)只能包含单个类型的值(a
)。
Haskell也有多态数字文字,因此如果我们限制1
的类型,错误会更加清晰:
λ Nothing : [1 :: Int, Nothing]
<interactive>:1:12: error:
• Couldn't match expected type ‘Maybe a’ with actual type ‘Int’
• In the expression: 1 :: Int
In the second argument of ‘(:)’, namely ‘[1 :: Int, Nothing]’
In the expression: Nothing : [1 :: Int, Nothing]
• Relevant bindings include
it :: [Maybe a] (bound at <interactive>:1:1)
Nothing
的类型为Maybe a
,1 :: Int
的类型为Int
。类型检查器无法找到方法
要使Maybe a
和Int
具有相同的类型,请报告错误。
如果您想要列出一些值和一些Nothing
,则需要使用Maybe a
的{{1}}构造函数:
Just
所以你要这样做:
Just :: a -> Maybe a
答案 1 :(得分:7)
简短回答:您可能想写[Just 1,Nothing]
。
<强>解释强>:
在Haskell中,列表只能包含一种类型的元素。因此,您不能在同一列表中混合使用Int
和String
。
如果你写:
[1, Nothing]
Haskell将致力于推导出类型。由于您编写了Nothing
,因此Haskell派生该列表包含Maybe a
类型的元素(它不知道哪个a
)。现在,它希望将1
转换为Maybe a
。可以使用类型类n
将数字文字转换为任何类Num n
。但是a
Maybe a
没有Num (Maybe a)
,因此Haskell会对此产生错误。
然而,你可以使用Just 1
,因为Haskell会得出a
的{{1}}类型为Maybe a
:
Num a