InitForTheLongRun
InitForTheLongRun

Reputation: 33

Using Recursion to get the sum sqrt of a list

Ive been trying to create a recursive function that takes a list of integers and gets the sum of the square root. i've come from c# and im pretty new to haskell. I feel as though ive hit a comprehension block

i was having problems with types so i tried making an integer sqrt to help myself out, but ended up confusing myself more..

isqrt :: Integer -> Integer
isqrt = floor . sqrt . fromIntegral

sumsquares :: Int a => [a] -> a
sumsquares f [] = "List is Empty"
sumsquares f (x:xs) | sum . isqrt  x | x <- xs

ive only done a little recursion and i can't find anywhere that really explains it in a way i understand

Upvotes: 2

Views: 803

Answers (2)

Shoe
Shoe

Reputation: 76240

How your code is uncompilable

sumsquares :: Int a => [a] -> a

The type signature is weird. Int is a type but you are using with the class syntax. What you really meant ("a list of integers") was:

[Integer] -> Integer

You are also taking as an argument an f that simply isn't there. This makes me think that you thought Int a => was an argument. It's not. Anything in the form X a => is a type class constraint that does not contribute to the arity of the function.

Then we have:

sumsquares f [] = "List is Empty"

This is unreasonable and incorrect. Generally speaking one would expect that the sum of an empty list is 0 or mempty (that's for a more complicated topic). "List is Empty" is a String (unless OverloadedString is in place), so that line wouldn't even compile.

Finally:

sumsquares f (x:xs) | sum . isqrt  x | x <- xs

I don't know what you were trying to do here, but | is used for conditionals. For example:

sumSquares :: [Integer] -> Integer
sumSquares x
    | null x    = 0
    | otherwise = (isqrt . head $ x) + tail x

Solution with explicit recursion

That would be like this:

sumSquares :: [Integer] -> Integer
sumSquares []       = 0
sumSquares (x:xs)   = isqrt x + sumSquares xs

Solution with map

Using map, it's simply:

sumSquares :: [Integer] -> Integer
sumSquares = sum . map isqrt

Upvotes: 2

MathematicalOrchid
MathematicalOrchid

Reputation: 62818

Well, isqrt looks good.

The type signature on sumsquares is wrong; Int isn't a class, it's a type. So you probably wanted to write [Int] -> Int. Note also that Integer and Int aren't the same. (Int is typically 32-bit, whereas Integer can hold thousands of bits.)

Not sure what the f parameter is supposed to be for. (It's also not mentioned in your type signature, so that won't work.)

You can't have one equation return a string ("List is Empty") and another one return a number. They have to both return numbers. I would suggest that no numbers add up to zero.

You probably wanted to write something like

sumsquares :: [Integer] -> Integer
sumsquares [] = 0
sumsquares (x:xs) = isqrt x + sumsquares xs

Do you see why that works? The sumsquare of an empty list is just zero, otherwise apply isqrt to the first element, recursively sum the remaining elements, and add the two results.

Upvotes: 0

Related Questions