我正在尝试使用像this这样的映射函数来处理n-ary树,但我正在努力。
data NTree a = Leaf a | Node a [NTree a]
ntreeMap :: (a -> b) -> NTree a -> NTree b
ntreeMap f (Leaf x) = Leaf (f x)
ntreeMap f (Node y t) = Node (ntreeMap f y) (ntreeMap f t)
给了我
Type error in application *** Expression : ntreeMap f t *** Term : t *** Type : [NTree b] *** Does not match : NTree a
有人能给我一个关于我哪里出错的指针吗?感谢
答案 0 :(得分:9)
这里有两个问题。一个是你不需要在ntreeMap
案例中y
递归调用Node
,因为它属于a
而不是NTree a
:
ntreeMap f (Node y t) = Node (f y) (ntreeMap f t)
第二个是t
是一个树列表,你的函数只映射到一棵树上,所以它应该是
ntreeMap f (Node y t) = Node (f y) (map (ntreeMap f) t)
答案 1 :(得分:3)
BTW:你的类型是一个Functor。
关于Functors的一个有趣的事情是,类型只有一种方法可以成为一个Functor(并遵守Functor法则)。
因此可以自动派生Functor实例:
{-# LANGUAGE TemplateHaskell #-}
import Data.DeriveTH
data NTree a = Leaf a | Node a [NTree a]
$( derive makeFunctor ''NTree )
ntreeMap :: (a -> b) -> NTree a -> NTree b
ntreeMap = fmap
答案 2 :(得分:0)
虽然我认为Rüdiger的答案是我想在GHC 6.12中添加的最佳答案,但您可以自动为您的数据类型派生一个Functor实例:
{-# LANGUAGE -DeriveFunctor #-}
data NTree a = Leaf a | Node a [NTree a]
deriving Functor