mkrieger1
mkrieger1

Reputation: 23107

Select elements from two lists based on elements of third list in Haskell

I have two lists inputA and inputB containing items of some type and a third list select of Bools. I want to construct a list where the i-th element is the i-th element of inputA if the i-th element of select is True, or the i-th element of inputB otherwise.

This can be done like this:

result = [if x then a else b | (x, a, b) <- zip3 select inputA inputB]

For example:

> [if x then a else b | (x,a,b) <- zip3 [True,False,False,True] [10..] [100..]]
[10,101,102,13]

I wonder if there is some built-in function, say mapIfElse, which can be used like this to produce the same result:

result = mapIfElse select inputA inputB

Upvotes: 1

Views: 175

Answers (1)

bheklilr
bheklilr

Reputation: 54058

There isn't a built-in function for this that I know of, but you could more easily implement it as

import Data.Bool (bool)

-- I don't like bool's argument order
if_ :: Bool -> a -> a -> a
if_ cond a b = bool b a cond

-- If you are using base < 4.7 then Data.Bool.bool
-- does not exist so you can define if_ manually as
-- if_ True  a b = a
-- if_ False a b = b

mapIfElse :: [Bool] -> [a] -> [a] -> [a]
mapIfElse = zipWith3 if_

This would be a more idiomatic implementation in my opinion, since it describes the operation for one set of arguments then applies that operation to the list of arguments. Again, I don't know of an existing function to do this, but in the future if you want to search for functions of a given type try hoogle first.

Upvotes: 4

Related Questions