Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Haskell 如何将函数应用于树的所有元素?_Haskell_Recursion_Tree_Map Function - Fatal编程技术网

Haskell 如何将函数应用于树的所有元素?

Haskell 如何将函数应用于树的所有元素?,haskell,recursion,tree,map-function,Haskell,Recursion,Tree,Map Function,它接受一个函数,并将其应用于rosetree的每个元素。通过将函数allCaps映射到rosetreethings来测试结果。所有元素现在都应该用大写字母书写 我不知道如何使用递归来编写此函数。您已经在使用递归了。事实上,您使用的roseMap f本身就是: data RoseTree a = RoseNode a [RoseTree a] deriving Show things :: RoseTree String things = RoseNode "thing" [

它接受一个函数,并将其应用于rosetree的每个元素。通过将函数
allCaps
映射到rosetree
things
来测试结果。所有元素现在都应该用大写字母书写

我不知道如何使用递归来编写此函数。

您已经在使用递归了。事实上,您使用的roseMap f本身就是:

data RoseTree a = RoseNode a [RoseTree a] deriving Show

things :: RoseTree String
things = 
    RoseNode "thing" [
        RoseNode "animal" [
            RoseNode "cat" [], RoseNode "dog" []
        ],

        RoseNode "metal" [
            RoseNode "alloy" [
                RoseNode "steel" [], RoseNode "bronze" []
            ],
            RoseNode "element" [
                RoseNode "gold" [], RoseNode "tin" [], RoseNode "iron" []
            ]
        ],       
    ] 
-- Turns string into all upper case
allCaps :: String -> String
allCaps x = map toUpper x
-- This function uses allCaps as a helper function 
--  to turn the elements in tree into upper case
roseMap :: (a -> b) -> RoseTree a -> RoseTree b
roseMap  f  rtree = case rtree of
    RoseNode a []    ->  allCaps a
    RoseNode a sub   ->  Rose (allCaps a) (map (roseMap f sub)
因此,这里我们使用
fa
,并在子对象上执行映射

如果我们随后使用
allCaps
函数执行
roseMap
,我们得到:

roseMap :: (a -> b) -> RoseTree a -> RoseTree b
roseMap f (RoseNode a xs) = RoseNode (f a) (map (roseMap f) xs)
我们不需要自己实现映射,我们可以启用,让Haskell为我们完成工作:

Prelude Data.Char> roseMap allCaps things
RoseNode "THING" [RoseNode "ANIMAL" [RoseNode "CAT" [],RoseNode "DOG" []],RoseNode "METAL" [RoseNode "ALLOY" [RoseNode "STEEL" [],RoseNode "BRONZE" []],RoseNode "ELEMENT" [RoseNode "GOLD" [],RoseNode "TIN" [],RoseNode "IRON" []]],RoseNode "FRUIT" [RoseNode "APPLE" [RoseNode "GRANNY SMITH" [],RoseNode "PINK LADY" []],RoseNode "BANANA" [],RoseNode "ORANGE" []],RoseNode "ASTRONOMICAL OBJECT" [RoseNode "PLANET" [RoseNode "EARTH" [],RoseNode "MARS" []],RoseNode "STAR" [RoseNode "THE SUN" [],RoseNode "SIRIUS" []],RoseNode "GALAXY" [RoseNode "MILKY WAY" []]]]

提示:玫瑰树顶部的值会发生什么变化,每个子树会发生什么变化?它应该首先更改玫瑰树顶部的元素,然后对其余元素应用相同的函数,但我不知道如何将其转换为函数。谢谢您的回答。我还有一个问题。haskell的递归很难想象,我的意思是我无法想象递归的实现过程。因此,编写正确的递归表达式是很困难的。为了更好地理解递归,我可以在纸上或类似的东西上扩展函数的执行吗?Haskell中的递归与其他语言中的递归没有什么不同。这在Haskell(以及一般的函数式语言)中更为常见,因为这通常是在命令式语言中实现循环的唯一方法,而且在Haskell中比在命令式语言中效率更高。(我无法详细解释原因,但懒惰是其中很大一部分。)至于递归在这种特定情况下的工作原理:玫瑰树由一个
a
类型的标签和一系列其他(子)树组成。将
rosemapf
应用于这样一棵树,只需将
a
替换为
fa
,将每个子树
sub
替换为
rosemapfsub
。当子树列表为空时,递归最终结束(至少在实践中,理论上不必如此)。如果您尝试使用示例树或更简单的示例树来解决这个问题,我相信您很快就会理解它的工作原理。
Prelude Data.Char> roseMap allCaps things
RoseNode "THING" [RoseNode "ANIMAL" [RoseNode "CAT" [],RoseNode "DOG" []],RoseNode "METAL" [RoseNode "ALLOY" [RoseNode "STEEL" [],RoseNode "BRONZE" []],RoseNode "ELEMENT" [RoseNode "GOLD" [],RoseNode "TIN" [],RoseNode "IRON" []]],RoseNode "FRUIT" [RoseNode "APPLE" [RoseNode "GRANNY SMITH" [],RoseNode "PINK LADY" []],RoseNode "BANANA" [],RoseNode "ORANGE" []],RoseNode "ASTRONOMICAL OBJECT" [RoseNode "PLANET" [RoseNode "EARTH" [],RoseNode "MARS" []],RoseNode "STAR" [RoseNode "THE SUN" [],RoseNode "SIRIUS" []],RoseNode "GALAXY" [RoseNode "MILKY WAY" []]]]
{-# LANGUAGE DeriveFunctor #-}

data RoseTree a = RoseNode a [RoseTree a] deriving (Functor, Show)
Prelude Data.Char> fmap (map toUpper) things
RoseNode "THING" [RoseNode "ANIMAL" [RoseNode "CAT" [],RoseNode "DOG" []],RoseNode "METAL" [RoseNode "ALLOY" [RoseNode "STEEL" [],RoseNode "BRONZE" []],RoseNode "ELEMENT" [RoseNode "GOLD" [],RoseNode "TIN" [],RoseNode "IRON" []]],RoseNode "FRUIT" [RoseNode "APPLE" [RoseNode "GRANNY SMITH" [],RoseNode "PINK LADY" []],RoseNode "BANANA" [],RoseNode "ORANGE" []],RoseNode "ASTRONOMICAL OBJECT" [RoseNode "PLANET" [RoseNode "EARTH" [],RoseNode "MARS" []],RoseNode "STAR" [RoseNode "THE SUN" [],RoseNode "SIRIUS" []],RoseNode "GALAXY" [RoseNode "MILKY WAY" []]]]