How to implement this bend function?

The following are two types of Color and Plant data.

data Color = Red | Pink | White | Blue | Purple | Green | Yellow
   deriving (Show, Eq)

data Plant =
     Leaf
   | Blossom Color
   | Stalk Plant Plant
   deriving (Show, Eq)

Now I have to implement a function of the fold_plantfollowing type:

(x -> x -> x) -> (Color -> x) -> x -> Plant -> x

The way I understand the fold function is that it takes a list, and for each iteration, it removes the first element from the list and does something with that element.

Apparently, it fold_plant Stalk Blossom Leafis a unit on plants.

Now I know that in Haskell you perform the following functions:

fold_plant :: (x -> x -> x) -> (Color -> x) -> x -> Plant -> x
fold_plant = do something

But from here I do not know how the bend function will work in a factory.

+4
source share
3 answers

If we look at the signature of the function:

fold_plant :: (x -> x -> x) -> (Color -> x) -> x -> Plant -> x
--            \_____ _____/    \____ _____/    |      |      |
--                  v               v          v      v      v
--                stalk           blossom     leaf  tree  output

, stalk, blossom leaf. stalk s blossom b leaf l. ( ) , , :

fold_plant s b l = fold_plant'
    where fold_plant' = ...

, , fold_plant'. , a leaf, - , l:

fold_plant' Leaf = l

a (Blossom c) c, c :: Color x b, :

fold_plant' (Blossom c) = b c

, a stalk, : fold_plant' , fold_plant' a s :

fold_plant' (Stalk lef rig) = s (fold_plant' lef) (fold_plant' rig)

, :

fold_plant s b l = fold_plant'
    where fold_plant' Leaf = l
          fold_plant' (Blossom c) = b c
          fold_plant' (Stalk lef rig) = s (fold_plant' lef) (fold_plant' rig)
+5

- , . , "" . , , Lisp, Smalltalk, Ruby, JavaScript .., reduce, Haskell.

, , Haskell , , haskell, fold .

, , " fold, ", " , ", . , - , , , .

"" Haskell foldr :: Foldable t => (a -> b -> b) -> b -> t a -> b, , " a" Foldable f => t a , . , foldr :: (a -> b -> b) -> b -> [a] -> b. a b? (a -> b -> b) ?

Int a b: foldr :: (Int -> Int -> Int) -> Int -> [Int] -> Int wow..., ... , ? foldr int, , (+), Int ( , , Int ... Int... Int -> Int -> Int Int [Int], [Int] .. .. , [Int] ... , .

.

, , , . , ? , , foldr, Int ? foldr :: (Int -> (Int, Int) -> (Int, Int)) -> (Int, Int) -> [Int] -> (Int, Int). , , Int , Int [Int]. , next [Int], , .

foldToMinMax = foldr (\newNum (minnum,maxnum) -> (min minnum newNum, max maxnum newNum)) (maxBound :: Int, minBound :: Int)

, .

? , , , , , . , , , - : foldr :: (contentOfCollectionType -> resultType -> resultType) -> resultType -> (collectionWrapper contentOfCollectionType) -> resultType

foldr , , - . , . , .

, , , . http://happylearnhaskelltutorial.com . , , ... , , , .

, . , a Color x. , , " x " (.. x x, (+) ). , , Color x, , .

.

!

+1

- :

    data Plant =                        data Result r =    
         Leaf                                RLeaf 
       | Blossom Color                     | RBlossom Color
       | Stalk Plant Plant                 | RStalk r r
            -- recursive data           -- non-recursive data: `r`, not `Result r`!

:

    -- single-step reduction semantics:
    -- reduction_step :: ..... -> Result r -> r
    reduction_step :: (r -> r -> r) -> (Color -> r) -> r -> Result r -> r
    reduction_step s b l  RLeaf       = l
    reduction_step s b l (RBlosom c)  = b c
    reduction_step s b l (RStalk x y) = s x y

, , , , , , fold_plant, , (!):

    recurse_into :: (r -> r -> r) -> (Color -> r) -> r -> Plant -> Result r
    recurse_into s b l Leaf          = RLeaf
    recurse_into s b l (Blossom c)   = RBlossom c
    recurse_into s b l (Stalk lt rt) = RStalk (fold_plant s b l lt) (fold_plant s b l rt)

, , ,

    fold_plant :: (r -> r -> r) -> (Color -> r) -> r -> Plant -> r
    fold_plant s b l plant = reduction_step s b l          --          Result r -> r
                               (recurse_into s b l plant)  -- Plant -> Result r

, , .

, , , , .

( ).

0

Source: https://habr.com/ru/post/1680757/


All Articles