树的Haskell地图

DB *_*sai 6 tree haskell

我的树是由

data Tree a = Leaf a | Node (Tree a) (Tree a) 
        deriving (Show)
Run Code Online (Sandbox Code Playgroud)

我还宣布了一个测试树.

myTree = Node (Node (Leaf 1) (Leaf 2)) (Leaf 3)
Run Code Online (Sandbox Code Playgroud)

我想要做的是创建一个函数maptree f,它将作用于Leaf.更具体地说f x = x +1,

然后maptree f myTree会回来

Node (Node (Leaf 2) (Leaf 3)) (Leaf 4)
Run Code Online (Sandbox Code Playgroud)

我的解决方案是

maptree f (Leaf a)= Leaf (f a)
maptree f (Node xl xr ) = Node (maptree xl) (maptree xr)
Run Code Online (Sandbox Code Playgroud)

但它会返回以下错误

Couldn't match expected type `Tree a'
       against inferred type `Tree t -> Tree t'
Probable cause: `maptree' is applied to too few arguments
In the first argument of `Node', namely `(maptree xl)'
In the expression: Node (maptree xl) (maptree xr)
Run Code Online (Sandbox Code Playgroud)

失败,模块加载:无.

但是,如果我这样做

maptree (Leaf a)= Leaf ( a + 1)
maptree (Node xl xr ) = Node (maptree xl) (maptree xr)
Run Code Online (Sandbox Code Playgroud)

它确实有效.

我看不出第一个功能和第二个功能之间的区别.我怎么得到错误?谢谢.

KQ.*_*KQ. 12

你错过了递归maptree调用的函数:

maptree f (Leaf a)= Leaf (f a) 
maptree f (Node xl xr ) = Node (maptree xl) (maptree xr)
Run Code Online (Sandbox Code Playgroud)

应该

maptree f (Leaf a)= Leaf (f a) 
maptree f (Node xl xr ) = Node (maptree f xl) (maptree f xr)
Run Code Online (Sandbox Code Playgroud)


ham*_*mar 8

请注意,这显然fmapFunctor您的Tree类型的实例.因此,您可以使用DeriveFunctor扩展程序让GHC为您生成它.

{-# LANGUAGE DeriveFunctor #-}
data Tree a = Leaf a | Node (Tree a) (Tree a) 
    deriving (Functor, Show)
Run Code Online (Sandbox Code Playgroud)

我们来试试吧.

*Main> fmap (+1) (Node (Node (Leaf 1) (Leaf 2)) (Leaf 3))
Node (Node (Leaf 2) (Leaf 3)) (Leaf 4)
Run Code Online (Sandbox Code Playgroud)


Jud*_*son 5

错误消息基本上告诉你什么是错的:你没有传递maptree足够的参数.定义maptree f (Node xl xr)maptree有两个参数,一个函数和一个树.但是当你把它称之为时maptree xl,你只给它一个参数(一棵树).

在第二个版本中,您已定义maptree为只接受一个参数(树),这就是它不会产生该错误的原因.

您可以通过调用maptree f xl而不是调用来解决问题maptree xl.


Dan*_*ton 5

当您更深入地递归(对于这种高阶函数)时,不要忘记传递函数的一种愚蠢方法是使用助手:

maptree f (Leaf a)     = Leaf (f a)
maptree f (Node xl xr) = Node (go xl) (go xr)
    where go = maptree f
Run Code Online (Sandbox Code Playgroud)

或者,或者(也许更常见):

maptree f tree = go tree                      -- or eta reduce:   maptree f = go
    where go (Leaf a)     = Leaf (f a)
          go (Node xl xr) = Node (go xl) (go xr)
Run Code Online (Sandbox Code Playgroud)

在第一个示例中,我使用gosort of 作为maptree f. 在第二个示例中,我利用了这样一个事实,即maptree的输入fgo函数内部的范围内,因为它go是在 的where子句中声明的maptree