Haskell-使用Just或no Just有所作为,但不知道为什么
题
我在"真实世界Haskell"一书中找到了这样的代码,p68
data Tree a = Node a (Tree a) (Tree a)
| Empty
deriving (Show)
nodeAreSame (Node a _ _) (Node b _ _)
| a == b = Just a
nodeAreSame _ _ = Nothing
我的问题是:做了什么工作 Just
数据构造函数做什么?当我删除它,我会得到错误信息,如
(in ghci)
......
<Main *> nodeAreSame (Node 3 Empty Empty) (Node 3 Empty Empty))
<interactive>:1:16:
No instance for (Num (Maybe a))
......
但是当我尝试比较"Just"和"No Just"版本之间的类型差异时:
nodeAreSameJust :: (Eq t) => Tree t -> Tree t -> Maybe t
nodeAreSameNoJust :: (Eq a) => Tree (Maybe a) -> Tree (Maybe a) -> Maybe a
那么这里的关键点是什么?这是否意味着当我把一个var与类型 a
在节点中,函数不会输出具有类型的节点 a
, ,所以它得到一个错误?
解决方案
事实上,没有 Just
是否 不是 把它弄得乱七八糟。
事情是这样的。守则
nodeAreSame (Node a _ _) (Node b _ _)
| a == b = a
nodeAreSame _ _ = Nothing
是 类型良好,但条件是 a
和 b
类型 Maybe t
对于一些 t
, ,因为这是 Nothing
.因此类型系统做出这种推断。
现在,当你有一个数字文字像 3
, ,推断为类型 Num s => s
直到你真正将它提交到一个特定的数据类型(如 Int
或 Double
).
所以当它把这两个事实放在一起时,它假设如下:
Num (Maybe t) => 3 :: Maybe t
.
因为没有实例 Num (Maybe t)
, ,它在那一点上抱怨,然后才有机会抱怨 3 :: Maybe t
毫无道理。
其他提示
你还能得到什么回报呢? a
?那行不通,因为 a
和 Nothing
不是同一种类型的。函数的所有定义都必须返回相同的类型。 Nothing
和 Just a
匹配,因为他们都是类型 Maybe a
.
在no just版本中,它需要树中的项目是类型的。
我并不完全确定错误的原因是num(也许a)。我认为如果使用字符串而不是3,则错误更为启发。
*Main> nodeAreSameNoJust (Node "arst" Empty Empty) (Node "arst" Empty Empty)
<interactive>:1:24:
Couldn't match expected type `Maybe a'
against inferred type `[Char]'
In the first argument of `Node', namely `"arst"'
In the first argument of `nodeAreSameNoJust', namely
`(Node "arst" Empty Empty)'
In the expression:
nodeAreSameNoJust
(Node "arst" Empty Empty) (Node "arst" Empty Empty)
.
这里更清楚它是期待类型的东西。在这两种情况下,该函数的第二个例子都没有,所以结果类型被推断为也许a。通过包括刚刚,将在树中使用的值放入可能类型。没有这个,它期望由此产生的a与没有的类型是相同的类型,因为该功能的每个部分需要是相同的类型。