1

Hi I'm trying to sum a list of tuples into a tuple with the foldl function, I tryed it with using as parameter a lambda expresion but it's giving out a wrong value here the code:

data Point = Point {x,y :: Float}
sumPoint :: [Point] -> (Float,Float)
sumPoint xs = foldl (\(a,b) x-> (0+a,0+b)) (0.0,0.0) xs

It should come out sumPoint [Point 2 4, Point 1 2, Point (-1) (-2)] = (2.0,4.0) But im getting (0.0,0.0) How is this making any sense?

Kevin
  • 145
  • 7
  • 5
    Well you're entirely ignoring `x` and `0+a` is the same as `a`, so you can see there's definitely no summation going on here. Try changing your lambda to something that adds two tuples. – amalloy Nov 14 '19 at 08:32
  • 1
    Oh I see, so it should be something like this? `sumPoint xs = foldl (\(a,b) (x,y)-> (x+a,y+b)) (0.0,0.0) xs` but I'm getting a strange error, it expects `[(Float, Float)]` actual type `[Point]` but Point is a (Float,Float) – Kevin Nov 14 '19 at 08:38
  • 2
    @Kevin Close. Try `(\(a,b) (Point x y)-> (x+a,y+b)) ` since the second argument is a point, not a pair. – chi Nov 14 '19 at 09:00
  • @chi Thanks for the tip it works out, I thought since point is defined as a pair the pattern should match. – Kevin Nov 14 '19 at 09:06
  • Haskell uses nominal typing (like most programming languages), where even if two types are defined in the same way but have a different name they are considered distinct types. Here, `Point` and `(Float,Float)` are structurally identical, but have a different name, so there is no automatic conversion. – chi Nov 14 '19 at 09:11

2 Answers2

3

To be a little structural you better define operations among Point type values and then convert the Point type to Tuple wherever needed. Otherwise you may directly use Tuple and discard the Point type.

data Point = Point {x,y :: Float} deriving Show

toTuple :: Point -> (Float, Float)
toTuple p = (x p, y p)

addPts :: Point -> Point -> Point
addPts p q = Point (x p + x q) (y p + y q)

sumPts :: [Point] -> Point
sumPts = foldl addPts (Point 0 0)

So what you need is toTuple . sumPts function.

*Main> :t toTuple . sumPts
toTuple . sumPts :: [Point] -> (Float, Float)
Redu
  • 25,060
  • 6
  • 56
  • 76
2

I changed it to

sumPoint xs = foldl (\(a,b) (Point x y)-> (x+a,y+b)) (0.0,0.0) xs

The problem was I was ignoring the x and at 0+a is nothing happening.

Kevin
  • 145
  • 7