我在"真实世界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

类型良好,但条件是 ab 类型 Maybe t 对于一些 t, ,因为这是 Nothing.因此类型系统做出这种推断。

现在,当你有一个数字文字像 3, ,推断为类型 Num s => s 直到你真正将它提交到一个特定的数据类型(如 IntDouble).

所以当它把这两个事实放在一起时,它假设如下:

Num (Maybe t) => 3 :: Maybe t.

因为没有实例 Num (Maybe t), ,它在那一点上抱怨,然后才有机会抱怨 3 :: Maybe t 毫无道理。

其他提示

你还能得到什么回报呢? a?那行不通,因为 aNothing 不是同一种类型的。函数的所有定义都必须返回相同的类型。 NothingJust 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与没有的类型是相同的类型,因为该功能的每个部分需要是相同的类型。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top