markoub
markoub

Reputation: 185

Map list of functions on list in Haskell

I have a problem with implementing FP (Backus) interpreter in Haskell.

FP functions look like this:

[+,*]:<2,3>

should result with

<+:<2,3>, *:<2,3>> ->
<5,6>

meaning that every function from list on left side should be performed on every every element of a list on a right side.

What I understand is that I need something similar to "map" function, but map applies one function on a list, and I need list of functions on a list of values.

Thank you in advance! :-)

EDIT:

Since I wasn't precise, here is my code that doesn't work:

apply :: [String] -> [Integer] -> [Integer]
apply fs v = [((apply_f f x) | f <- fs | x <- v)]

apply_f :: String -> [Integer] -> [Integer]
apply_f "+" v = [(sum v)]
apply_f "*" v = [(product v)]

I can't figure out why... :-(

EDIT 2:

Sorry, I was too tired from working all day on this. Problem is that I don't need second pipe, just first one:

apply fs v = [ apply_f f v | f <- fs ]

Now, everything works just fine, thank you very much! :-)

Upvotes: 8

Views: 8737

Answers (5)

Nymer
Nymer

Reputation: 261

Do you want something like this?

[f x | f <- [(+3),(*2)], x <- [1..2]]

Output:

[4,5,2,4]

EDIT:

So something like this?

[[f x | f <- [(+3),(*2)]] | x <- [1..2]]
[[4,2],[5,4]]

Upvotes: 6

Rotsor
Rotsor

Reputation: 13793

I can't figure out anything from your explanation, but here is a possible code, which gives the correct answer for your example:

> map (uncurry foldr1) [((+), [2,3]), ((*), [2,3])]
[5,6]

Upvotes: 0

Dervall
Dervall

Reputation: 5744

I believe you are looking for the zipWith function and apply it with the function application operator $.

So, if you have a list of functions funcList and a list of values valueList you would call this with:

zipWith ($) funcList valueList

So, using this would be something like

zipWith ($) [(+ 5),(* 3)] [1,5]

gives you the result [6,15]

To get a sort of cross application you could use

[f a | f <- [(+5), (*3)], a <- [1,5]]

this gives you [6,10,3,15]. Not sure what you mean by the `<, do you want pairs, nested lists or what exactly do you need?

Upvotes: 18

Oleksii Kachaiev
Oleksii Kachaiev

Reputation: 6232

I don't know if it's actually that you need, but

Prelude> [f 2 3 | f <- [(+), (*)]]
[5,6]

If you need lists of <2,3> pairs, you can use something like

Prelude> [zipWith f [2, 20] [3, 30] | f <- [(+), (*)]]
[[5,50],[6,600]]

Upvotes: -1

Lee
Lee

Reputation: 144176

It sounds like you want:

import Control.Applicative
apply :: [a -> b] -> [a] -> [b]
apply fs vals = fs <*> vals

Of course this is just the same as the instance of <*> defined for lists.

Upvotes: 17

Related Questions