Haskell树映射
我一直在尝试使用Haskell编写一个简单的映射函数,但遇到了以下问题:Haskell树映射,haskell,Haskell,我一直在尝试使用Haskell编写一个简单的映射函数,但遇到了以下问题: data Tree a = Leaf a | Node (Tree a) (Tree a) deriving(Show) let g (Leaf l) = Leaf(l+1) let map g (Leaf l) = g(l) let lf = (Leaf 2) 对于g(lf)而言,输出为Leaf 3,例外情况除外, 但是对于mapglf我得到以下错误: Couldn't match type `Integer'
data Tree a = Leaf a | Node (Tree a) (Tree a) deriving(Show)
let g (Leaf l) = Leaf(l+1)
let map g (Leaf l) = g(l)
let lf = (Leaf 2)
对于g(lf)
而言,输出为Leaf 3
,例外情况除外,
但是对于mapglf
我得到以下错误:
Couldn't match type `Integer' with `Tree a0'
Expected type: Tree (Tree a0)
Actual type: Tree Integer
In the second argument of `map', namely `lf'
In the expression: map g lf
In an equation for `it': it = map g lf
我不知道为什么会出现这个错误,如果有人能给我指出解决方案,我将不胜感激。这正是显示程序逻辑不正确的类型系统。我们可以通过手动添加大量额外的类型信息来跟踪细节,以查看我们的直觉是否与检查器的细节相匹配
data Tree a = Leaf a | Node (Tree a) (Tree a) deriving (Show)
g :: Num a => Tree a -> Tree a
g (Leaf l) = Leaf (l + 1)
map :: (a -> b) -> Tree a -> b
map g (Leaf l) = g(l)
lf :: Num a => Tree a
lf = (Leaf 2)
现在我们来看看失败的表达式
(map :: (a -> b) -> Tree a -> b)
(g :: Num c => Tree c -> Tree c)
(lf :: Num d => Tree d)
我们会注意到,(a->b)
必须与(Num c=>树c->树c)
匹配,从而使a
是树c
,而b
也是
(map g :: Tree (Tree c) -> Tree c)
(lf :: Num d => Tree d)
现在我们注意到d
必须与树c
匹配
map g lf :: Num (Tree c) => Tree (Tree c) -> Tree c
现在我们知道我们已经沉没了,因为Tree
s不是数字,但是您得到的错误略有不同。这是说树c
不是整数
发生这种情况是因为当您不提供类型签名时,Haskell会试图提供帮助并猜测您可能要处理的具体类型。当它这样做时,它有时会选择比严格可能更少的多态性。在这种情况下,它决定lf::Tree Integer
而不是lf::Num d=>Tree d
,因为前者更具体。请。