如何定义一个Haskell函数,该函数将函数应用于二叉树中的每个值?所以,我知道这是类似于map
功能 - 以及它的类型是:Haskell二叉树函数(地图)
mapT :: (a -> b) -> Tree a -> Tree b
但是那它...
如何定义一个Haskell函数,该函数将函数应用于二叉树中的每个值?所以,我知道这是类似于map
功能 - 以及它的类型是:Haskell二叉树函数(地图)
mapT :: (a -> b) -> Tree a -> Tree b
但是那它...
我会假装这是功课,而不是放弃所有的答案。如果我错了,我的道歉。
可能是你Tree
型看起来是这样的:
data Tree a = TreeNode a (Tree a) (Tree a) | EmptyNode
这里有两种情况,你将需要编写一个mapT
实施为他们每个人:
TreeNode
,其中携带a
类型的值,并具有左侧和右侧孩子。在这种情况下需要做什么?EmptyNode
。在这种情况下需要做什么?有趣的问题,如果输入和输出应该是排序二叉树。如果您只是天真地遍历树并应用该函数,则输出树可能不再被排序。例如,考虑如果函数是非线性的,如
f(x) = x * x - 3 * x + 2
如果输入具有{1,2,3,4},那么输出将具有{2,0,0,2}。输出树应该只包含0和2吗?
如果是这样,当您剥离并处理输入树时,您可能需要迭代地构建输出树。
地图功能的基本格式适用于两者。让我们看一下地图功能的定义列表:
map f (x:xs) = f x : map f xs
map _ [] = []
我们可以概括这个像这样:
您真正需要的是看你的构造和地图功能应该水到渠成。
您可以声明类Functor
的实例。这是允许映射函数的数据类型的标准类。请注意,fmap
类型的相似是你mapT
的类型:
class Functor f where
fmap :: (a -> b) -> f a -> f b
让我们假设你的树被定义为
data Tree a = Node (Tree a) (Tree a) | Leaf a
deriving (Show)
然后你就可以申报Functor
一个实例是这样的:
instance Functor Tree where
fmap f (Node l r) = Node (fmap f l) (fmap f r)
fmap f (Leaf x) = Leaf (f x)
这就是你如何使用它:
main = do
let t = Node (Node (Leaf 1) (Leaf 2)) (Leaf 3)
let f = show . (2^)
putStrLn $ "Old Tree: " ++ (show t)
putStrLn $ "New Tree: " ++ (show . fmap f $ t)
输出:
Old Tree: Node (Node (Leaf 1) (Leaf 2)) (Leaf 3)
New Tree: Node (Node (Leaf "2") (Leaf "4")) (Leaf "8")
您也可以定义为方便起见:
mapT = fmap
当然,你可以不用类型的类,但它使别人,如果你的代码更易读使用标准功能(每个人都知道fmap
的常见行为)。
这是功课吗?如果是这样,请相应标记。 – Thomas 2010-05-03 07:21:51
'mapT = fmap'? – kennytm 2010-05-03 08:34:12