[Haskell-beginners] pattern matching to data inside a list

Francesco Bochicchio bieffe62 at gmail.com
Fri Mar 27 10:05:14 EDT 2009


2009/3/27 Michael Mossey <mpm at alumni.caltech.edu>

> Is there a way to pattern match to a list argument and get a list? For
> example, I have this:
>
> -- A LayoutItem has a center position (point), and the four ints are
> -- "left width", "rigth width", "top height", and "bottom height"
> data LayoutItem = LayoutItem Point Int Int Int Int
>                deriving Show
>
> -- This computes the left width of a group of composited LayoutItem.
> compositeLeftWidth :: [LayoutItem] -> Int
> compositeLeftWidth items = let
>    itemsPosX = [ x | LayoutItem (Point (x,_)) _ _ _ _ <- items ]
>    itemsLW = [ lw | LayoutItem _ lw _ _ _ <- items ]
>    z = zipWith (\x y -> x-y+1) itemsPosX itemsLW
>    in (minimum z) - 1
>
> What I'm wondering is if I could somehow do something like
>
> compositeLeftWidth [ LayoutItem Point( x, _ ) lw _ _ _ ] = ...
>
> and that x and lw would each be the lists I'm calling itemsPosX and itemsLW
> above.
>
> Thanks,
> Mike
>
> That would be neat :-). But IIRC there is no syntax for that.
However, if you are interested in other suggestions (by a very newbie, so
they could be off-mark):

1. if you use a definition like this

 data LayoutItem = LayoutItem  { x :: Point;   leftw, rightw, toph, bottomh
:: Int }
               deriving Show
 then you could do, using the data accessor functions implicitely defined by
the above code:

             xlist = map x items
             lwlist = map leftw items

which is basically the same of your list comprehensions, but takes less
characters :-)

2. If I read correctly your code, you are processing a single element of
'items' per time. If so, instead
    of building lists of attributes and the zipWith them to get your result,
you could use this approach:

a. define a function tha process a single item of type Layout, like :

          compLW  LayoutItem x lw rw th bh = x - lw + 1
           -- not sure it has the same result, but you get the idea

b. use map (or list comprehension) to build z from items:

      compositeLeftWidth items = ( minimum z) -1
             where z = map  compLW items

This way you avoid to scan multiple times the same list.

Ciao
-------
FB
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://www.haskell.org/pipermail/beginners/attachments/20090327/04a1c058/attachment.htm


More information about the Beginners mailing list