pattern matching to data inside a list
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.
2009/3/27 Michael Mossey <mpm@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
participants (2)
-
Francesco Bochicchio -
Michael Mossey