[Haskell-beginners] Re: Padding List with Zeros

Ertugrul Soeylemez es at ertes.de
Wed Sep 15 10:09:21 EDT 2010


Henry Olders <henry.olders at mcgill.ca> wrote:

> Being a real Haskell newby, I can figure out a one-line solution in
> Python, but I don't know how to do something similar in Haskell, or
> even if it's possible. Please correct me if I'm wrong, but there does
> not seem to be a dictionary type in Haskell, and I am not aware of how
> to specify an inline if...else inside a list comprehension. I would
> really appreciate it if someone could show me how to do something
> similar to this Python statement in Haskell.
>
> >>> A=[0,10,20,30,40,50]
> >>> B=[0,10,50]
> >>> C=[2,1,-5]
> >>> [dict(zip(B,C))[a] if a in B else 0 for a in A]
> [2, 1, 0, 0, 0, -5]

There is a dictionary type, but it has a more general name than in
Python, which is quite common for Haskell data structures.  It's called
'Map' and is defined in the Data.Map module.  In general you want to
import that module qualified to avoid name clashes:

  import qualified Data.Map as M

Then you can use my solution from my other post, which is exactly
equivalent to your Python solution:

  substSubset :: (Num b, Ord a) => [a] -> [b] -> [a] -> [b]
  substSubset ys zs =
    map (\x -> M.findWithDefault 0 x (M.fromList $ zip ys zs))

I prefer to use higher order functions rather than list comprehensions,
because of better composability.  But you can just as well use a list
comprehension here:

  substSubset :: (Num b, Ord a) => [a] -> [b] -> [a] -> [b]
  substSubset ys zs xs =
    [ M.findWithDefault 0 x (M.fromList $ zip ys zs) | x <- xs ]

The findWithDefault function from Data.Map does this comparison
implicitly, but you can also do this instead:

  substSubset :: (Num b, Ord a) => [a] -> [b] -> [a] -> [b]
  substSubset ys zs xs =
    let dict = M.fromList (zip ys zs) in
    [ case M.lookup x dict of Just z -> z; Nothing -> 0 | x <- xs ]

If course a more direct translation is also possible, but you really
don't want that, because pattern matching is not only more elegant, but
also faster and doesn't require an Eq constraint.  Also note that your
Python code does two lookups per element, while mine does only one.

Anyway, it's really better to learn to use higher order functions
properly.  This greatly enhances both composability and code
readability.


Greets,
Ertugrul


-- 
nightmare = unsafePerformIO (getWrongWife >>= sex)
http://ertes.de/




More information about the Beginners mailing list