Peter
Peter

Reputation: 3164

Map `Nothing` returned by `lookup` to default value

Say I have a list l of type [(Int, Integer)] such that the first element in every tuple is a (unique) index i in the range 0 to n and the second element in every tuple is an associated value v.

I want to "expand" this list into a list of l' type [Integer] with length 10 such that l !! i == v for all (i,v) in l and l !! j == 0 if (j,_) is not in l.

I.e.: [(1,10),(6,7)] => [0,10,0,0,0,0,7,0,0,0]

I'm not sure how to do this, I have tried:

map (\i -> lookup i l) [0..n]

That works except that the result is a list of Maybe's. An obvious solution is:

integerOrZero :: Maybe Integer -> Integer                                        
integerOrZero Nothing  = 0                                                       
integerOrZero (Just n) = n    

And then:

map integerOrZero $ map (\i -> lookup i l) [0..n]

But I was wondering if there is a simpler way (maybe a one-liner) to write this "lookup with default". I guess mayMaybe doesn't work here.

Context: I'm trying to produce a histogram of values between 0 and n given a list of them, so overall I have thus far:

import Data.List (group, sort)

hist l = map integerOrZero $ map (\i -> lookup i l') [0..n]
  where l' = map (\x -> (head x, length x)) $ group $ sort l

I would like to write this as succinctly as possible using only functions from the base package.

Upvotes: 0

Views: 557

Answers (1)

Akihito KIRISAKI
Akihito KIRISAKI

Reputation: 1333

There is Data.Maybe.fromMaybe, it is often forgotten.

Data.Maybe

If you use Data.Map.Strict, there is a better choice. findWithDefault must be what you want.

Upvotes: 5

Related Questions