norm :: [Double] > Double norm (lst) = sqrt(sum' lst) squares (i : lst) = (i * i) : squares lst sum' [] = 0 sum' lst = sum (squares $ lst) main = print (norm [1.1, 2.2, 3.3])
3 Replies  1921 Views  Last Post: 09 July 2013  12:10 AM
#1
Help with Haskell program to compute sum of squares
Posted 06 July 2013  06:26 PM
Just starting learning Haskell. Can someone point out to me the errors?
Replies To: Help with Haskell program to compute sum of squares
#2
Re: Help with Haskell program to compute sum of squares
Posted 06 July 2013  06:40 PM
Your squares function doesn't have a case for when the list is empty. So when the recursion reaches that case, it'll cause an exception.
#3
Re: Help with Haskell program to compute sum of squares
Posted 08 July 2013  06:00 PM
first and foremost, you should consider sepp2k's response to learn what you did wrong. That said there are more idiomatic ways to do this, namely you should learn to use "map", impart to avoid these kinds of mistakes.
the map function is pretty boss and almost always a better pick that rolling your own recursion which, as much as possible, you should avoid. You will need recursion quite frequently but a lot of it can be avoided. using things like, zip, map, fold, etc... can clean things up a lot
This is the norm function you have implemented but written in "point free style" but more on that latter
Basically what I just wrote is this:
'map' iterates a list generating a new list by applying some function to it. just like your 'squares' function. It is such a common occurrence to do the kind of iteration you are doing that this function is provided in the Prelude (meaning it's already there like 'sum' or '*' or 'print').
to more closely follow your code I might write
now I will introduce the "pointfree" part. the above function can be written
this can seen more clearly if you look at the original with some parans
If you think about it this is saying "applying 'xs' to 'squares' is defined as applying 'xs' to '(map square)'". This definition should make it clear that 'squares' and '(map square)' are same because if you apply some arbitrary 'xs' to either of them they will yield the same result hence we can simply say squares = map square
notice I have not defined 'square' just yet. in my first example I used '(^ 2)' instead of square. this is because square = (^ 2). haskell is actually applying a value for the second argument here rather than the first as it is to the right of the operator but the idea is the same as above.
this is the same as saying square = \x > x ^ 2 which is in turn the same as square = (^ 2) and finally we have the '.' operator. the '.' is the "compose" function which you may have seen in a math class.
so (sqrt . sum) [1, 2, 3] is the same as sqrt (sum [1, 2, 3])
and (sqrt . sum . squares)[1, 2, 3] is the same thing as sqrt (sum (squares [1, 2, 3])) and because 'squares' is the same thing as map (^ 2) we can substitute to get what I have above
Functions are the work of gods if you ask me. There is an expression that goes something like "god invented integers; all else is man's work", I like to say "god invented lambda calculus; all else is man's work"
the map function is pretty boss and almost always a better pick that rolling your own recursion which, as much as possible, you should avoid. You will need recursion quite frequently but a lot of it can be avoided. using things like, zip, map, fold, etc... can clean things up a lot
norm = sqrt . sum . (map (^ 2))
This is the norm function you have implemented but written in "point free style" but more on that latter
Basically what I just wrote is this:
norm xs = sqrt (sum (map square xs))
'map' iterates a list generating a new list by applying some function to it. just like your 'squares' function. It is such a common occurrence to do the kind of iteration you are doing that this function is provided in the Prelude (meaning it's already there like 'sum' or '*' or 'print').
to more closely follow your code I might write
squares xs = map square xs
now I will introduce the "pointfree" part. the above function can be written
squares = map square
this can seen more clearly if you look at the original with some parans
squares xs = (map square) xs
If you think about it this is saying "applying 'xs' to 'squares' is defined as applying 'xs' to '(map square)'". This definition should make it clear that 'squares' and '(map square)' are same because if you apply some arbitrary 'xs' to either of them they will yield the same result hence we can simply say squares = map square
notice I have not defined 'square' just yet. in my first example I used '(^ 2)' instead of square. this is because square = (^ 2). haskell is actually applying a value for the second argument here rather than the first as it is to the right of the operator but the idea is the same as above.
square x = x ^ 2
this is the same as saying square = \x > x ^ 2 which is in turn the same as square = (^ 2) and finally we have the '.' operator. the '.' is the "compose" function which you may have seen in a math class.
compose f g x = f (g x)
so (sqrt . sum) [1, 2, 3] is the same as sqrt (sum [1, 2, 3])
and (sqrt . sum . squares)[1, 2, 3] is the same thing as sqrt (sum (squares [1, 2, 3])) and because 'squares' is the same thing as map (^ 2) we can substitute to get what I have above
norm = sqrt . sum . (map (^ 2))
Functions are the work of gods if you ask me. There is an expression that goes something like "god invented integers; all else is man's work", I like to say "god invented lambda calculus; all else is man's work"
This post has been edited by ishkabible: 08 July 2013  07:55 PM
#4
Re: Help with Haskell program to compute sum of squares
Posted 09 July 2013  12:10 AM
That makes perfect sense, and is very helpful. Thanks ishkabible.
Thanks sepp2k for your help too.
Thanks sepp2k for your help too.
Page 1 of 1
