我正在尝试实现一个haskell程序,它使用仿函数递增树中所有节点的值。输入&仿函数函数的输出是树。我试图递归地实现它,但是有关输入参数的编译错误。
Haskell代码..
data Tree v = Empty | Node v (Tree v) (Tree v) deriving (Show)
add :: Ord v => v -> Tree v -> Maybe Tree v
add _ Empty = Nothing
add v (Node val left right) = (val + v) ++ add v left ++ add v right
输入
add (+1) (Node 3 (Node 1 Empty Empty) (Node 7 (Node 4 Empty Empty) Empty))
输出
[1 of 1] Compiling Main ( functor1.hs, interpreted )
functor1.hs:17:34: error:
* Expecting one fewer arguments to `Maybe Tree'
Expected kind `* -> *', but `Maybe Tree' has kind `*'
* In the type signature:
add :: Ord v => v -> Tree v -> Maybe Tree v
|
17 | add :: Ord v => v -> Tree v -> Maybe Tree v
| ^^^^^^^^^^^^
functor1.hs:17:40: error:
* Expecting one more argument to `Tree'
Expected a type, but `Tree' has kind `* -> *'
* In the first argument of `Maybe', namely `Tree'
In the type signature:
add :: Ord v => v -> Tree v -> Maybe Tree v
|
17 | add :: Ord v => v -> Tree v -> Maybe Tree v
| ^^^^
Failed, no modules loaded.
语法中是否有错误?请帮忙
答案 0 :(得分:1)
我正在尝试递归地实现它,但是有关输入参数的编译错误。
编译时没有错误,因此永远不会编译add
,因此它不起作用。
语法和语义都存在一些问题,以及一些奇怪的设计决策。
首先,如果你写Maybe Tree v
,Haskell会将其视为(Maybe Tree) v
,据我所知 - 这不是预期的结果,它应该是Maybe (Tree v)
将Tree v
打包到Maybe
。
但是使用Maybe (Tree v)
作为结果已经有点奇怪了:无论你提供什么输入树,我们都应该构建一个 new 有效Tree
。对于Empty
,我们只是不添加任何值,因此add 3 Empty == Empty
,但没有可能出错的情况。
你也Ord v
作为类型约束,这很奇怪,因为在函数中,我们从不使用==
,/=
,<
,{{1等功能。我们使用>
,这意味着我们应该使用+
,所以现在我们的签名是:
Num v
我们可以实现两种情况:一种用于add :: Num v => v -> Tree v -> Tree v
(保持Empty
),一种用于Empty
(用于更新值,并执行两次递归调用),例如: / p>
Node
您的问题表明您要实施add :: Num v => v -> Tree v -> Tree v
add _ Empty = Empty
add v (Node x l r) = Node (v+x) (add v l) (add v r)
。定义Functor
与此处的fmap
非常相似,但需要概括第一个参数。我把它留作练习。
如果你打电话给:
add
第一个参数是不是一个数字,而是一个函数,因此在这种情况下你应该放弃add (+1) (Node 3 (Node 1 Empty Empty) (Node 7 (Node 4 Empty Empty) Empty))
:
+
制造
add 1 (Node 3 (Node 1 Empty Empty) (Node 7 (Node 4 Empty Empty) Empty))