Question

I need to define a function that receives a tuple t1 (String,(Int,Int,Int) and another tuple t2 (String,[(String,Int,[Fs])]). It has to return the tuple t1 with modified values in its second element (Int,Int,Int). This alterations are caused by the functions stored in the tuple t2.

If I'm correct, first I need to generate a list of functions from the second tuple, which I did with fold:

trd3 (a,b,c) = c
listFunctions = foldr (++) [] (map trd3 (snd t2))

The problem appears when I want to use fold again to compose the list of functions, that it's not working:

foldr (.) (snd t1) (foldr (++) [] (map trd3 (snd t2)))

As an example, I could say that

t1 = ("Warrior",(15,5,12))
t2 = ("Bag",[("HP potion",5,[f1,f2]),("MP potion",3,[f3])])
f1 (a,b,c) = (a+10,b+5,c)
f2 (a,b,c) = (a+5,b+5,c)
f3 (a,b,c) = (a,b+5,c+15)

So the function should return something like (f3 . f2 . f1) (15,5,12)

I have also seen this link: http://haskell.org/haskellwiki/Compose but can't understand it 100%.

If someone could explain how to work this out, that would be really appreciated.

Thanks a bunch.

Was it helpful?

Solution

The problem is where you put the snd t1.

foldr (.) (snd t1) (foldr (++) [] (map trd3 (snd t2)))

Let's pretend for a moment that this type checked, then this would evaluate to

f3 . f2 . f1 . snd t1

which is nonsense because snd t1 isn't a function, so you can't compose it.

What you want to do is to first compose the functions, then apply the resulting function to snd t1. You can do this by using id as the second argument to foldr, i.e.

foldr (.) id (foldr (++) [] (map trd3 (snd t2))) $ snd t1

which evaluates to

f3 . f2 . f1 . id $ snd t1

which is of course the same as

f3 . f2 . f1 $ snd t1

which is what you wanted.

OTHER TIPS

I'm not sure I fully understand the question, but you can compose a list of a -> a (endofunctions) using Foldable and the Endo Monoid:

-- Given some listOfFunctions :: [a -> a] and initialValue :: a, for some type a:
appEndo (foldMap Endo listOfFunctions) initialValue

For example:

λ> import Data.Foldable (foldMap)
λ> import Data.Monoid
λ> appEndo (foldMap Endo [(+2), (*10), (/2)]) 50  -- This evaluates ((50/2)*10)+2
252.0
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top