pattern matching to data inside a list

classic Classic list List threaded Threaded
2 messages Options
Reply | Threaded
Open this post in threaded view
|

pattern matching to data inside a list

Michael Mossey
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

PS Let me repeat my request to find out how to install SOE "on the
library path." I know I'm impatient about this, but it seems simple
enough, and it's driving me crazy that I can only write software in the
same directory where I've installed SOE.
Reply | Threaded
Open this post in threaded view
|

pattern matching to data inside a list

Francesco Bochicchio
2009/3/27 Michael Mossey <[hidden email]>

> 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