Reputation: 49
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.
Upvotes: 1
Views: 1645
Reputation: 139850
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.
Upvotes: 3
Reputation: 10783
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
Upvotes: 0