[Haskell-cafe] A function using List and Tuple

Sebastian Sylvan sylvan at student.chalmers.se
Mon Jun 19 01:32:59 EDT 2006


On 6/19/06, Sara Kenedy <sarakenedy at gmail.com> wrote:
> Hello,
>
> I want to creat a function sumList as below examples:
> sumList [("s1",2),("s2",4),("s3",3),("s4",2)] = ("#", 1/2 + 1/4 + 1/3 + 1/2)
> sumList [("s1",2),("s2",4),("s3",3) =  ("#", 1/2 + 1/4 + 1/3)
>
> I attempted it as following:
>
> sumList :: (Fractional a) => [(String,a)] -> (String, a)
> sumList [] = ???
> sumList (x:xs) = ("#", 1/(snd x) + 1/snd(sumList xs))
>
> I know this function cannot give the correct answer (even if I define
> sumList []), but I did not find the right way.
> If anyone can give me a suggestion, I really appereciate for that. Thanks.
>

There are numerous ways to write this of course, but I would suggest a
less "direct" appoach. You don't really need to write out the explicit
recursive definition.
Try to "massage" the data to the form you need it in, after a few
transformations of the data the answer is hopefully a lot easier to
produce.

So:
sumList xs = ("#", s)
       where s = ...

Would be a good start. The computation of the sum doesn't need to
worry about the final tuple form with the "#", so we do that at the
end, and produce the sum in the where-clause.

Now s depends only on the the second elements of the tuples in the
list (if I understand the problem correctly), so you could "massage"
the input to help clean out the bits that aren't needed (that is, we
want a list containing the second elements of each tuple):

sumList xs = ("#", s)
       where s = ...
                 ys = map snd xs

Now the problem is much simpler, you just need to take one divided by
each element of ys and sum the results up to produce s.

sumList xs = ("#", s)
       where s = sum zs
                 ys = map snd xs
                 zs = map (\x ->1/x) ys

Or how about this simplification using a list comprehension.
sumList xs = ("#", s)
       where s = sum [ 1/x | (_, x) <- xs ]

Even shorter:
sumList xs = ( "#", sum [ 1/x | (_, x) <- xs ] )

No recursion required! (at least not visibly, sum uses it in its
definition). There are plenty of really useful functions in the
Prelude and Data.List (and other modules), so for simple functions you
rarely need to write out a full recursive solution, but rather use
some of the useful library functions to compose the result in a very
readable form.

/S
-- 
Sebastian Sylvan
+46(0)736-818655
UIN: 44640862


More information about the Haskell-Cafe mailing list