[Haskell-beginners] Complex list manipulation

Daniel Fischer daniel.is.fischer at web.de
Tue Nov 10 16:45:16 EST 2009


Am Dienstag 10 November 2009 22:09:36 schrieb legajid:
> Hello,
> i'm trying to manipulate lists with a "complex" (two-level) structure :
> a list containing tuples, containing a list containing tuples.
> The object is to find a specific value according to 2 criterias.
>
> Here is my code
>
> tabmul= [ ( a, [ ( n, n*a ) | n <- [1..9] ] ) | a <- [2,3,4] ]
>
> {- gives the following list
> [
>  (2, [(1,2), (2,4), ....(9,18)]),
>  (3, [(1,3), (2,6), ....(9,27)]),
>  (4, [(1,4), (2,8), ....(9,36)])
> ]
> -}
>
>
> {-  Get the result for a=3 and n=5  -}
>
> -- select level 1 tuple for a=3
> s1_flt (x,_) = (x==3)
> s1=filter (s1_flt) tabmul -- get the list  [(3, [(), () .......])]

filter ((== 3) . fst) tabmul

> s1_liste =head(s1)        -- get the tuple (3, [.....])

You might want to use

Data.List.lookup :: (Eq a) => a -> [(a,b)] -> Maybe b

lookup 3 tabmul 
~> Just [(1,3),...]

>
> -- extract the level 2 list of tuples
> s1_tup (x,y)=y

That's Prelude.snd (fst (a,b) = a; snd (a,b) = b)

>
> -- then tuple for n=5
> s1_flt2 (x, y) = x==5

(== 5) . fst

> s1_soltup = filter (s1_flt2) (s1_tup s1_liste)  -- [(3,15)]
>
> --finally result for 3 * 5
> s1_sol1 (x, y)= y
> s1_sol = s1_sol1 (head s1_soltup)

lookup 3 tabmul >>= lookup 5

or

do listetrois <- lookup 3 tabmul
   lookup 5 listetrois

~> Just 15

>
>
> Perhaps the structure is not the most efficient for this example, but it
> may simulate records in a database.
> Getting the result seems really hard.
> Do you know a shorter way to implement this search?
> It probably would be simpler when i had triples (a, n ,a*n) ?

Not necessarily, there are 

fst :: (a,b) -> a

and

snd :: (a,b) -> b

in the Prelude, but not the analogous functions for triples or larger tuples.

head . filter ((== val) . fst)

is pretty simple, but if you want to use association lists as maps, lookup is even more 
handy.

>
> Another question : the values of criterias are hard-coded. What if i
> would like to type in s1_sol 3 5; how to put these parameters in the
> expressions for filters; the filters must get the parameters of the
> function, in other words the function should return or generate filters ?

résultat x y = lookup x tabmul >>= lookup y

résultat x y = do
    liste <- lookup x tabmul
    lookup y liste

résultat x y = head . filter ((== y) . fst) . snd . filter ((== x) . fst) $ tabmul

In my book, the first two are clear winners.

>
> Thanks for helping
> Didier.




More information about the Beginners mailing list