What a bottom (which is _|_) in haskell? - haskell

In Haskell document, sometime I find the word bottom (_|_). Is it correct that a bottom (_|_) is a value cannot be further broken down?
Example,
Non-bottom:
a Num is not, because, it an instance of class Num.
1 is not, because, it is a Num.
a String is not, because, it is a list of Char
"aa" is not, because it is a String
...
A-Bottom: following are all a bottom, because they cannot be further broken down.
a Char
an Int
1::Int
a Word
1::Word
Apple and Orange in data Fruit = Apple | Orange
...

Your intuition is incorrect. A bottom is a fictional value representing a non-terminating program. In Haskell, because of laziness, this value is present in any type.
For example:
x1 :: Integer
x1 = 42 -- not a bottom
x2 :: Integer
x2 = sum [1..] -- bottom, it does not terminate
x3 :: (Integer, String)
x3 = x3 -- bottom, infinite recursion
x4 :: (Integer, String)
x4 = (x2, "hello") -- not a bottom, but a pair (_|_, "hello")
We also pretend that undefined and error ".." are bottoms, since these are exceptional values of expression that fail to evaluate to a "proper" value in their type.
The name bottom comes from theoretical computer science, where mathematical models of computation are studied. In practice, it is common there to "order" the values in functional programming languages so that "non-termination" corresponds to the smallest possible value, which lies at the "bottom" of the ordering, hence the "bottom" name.
E.g. the following pairs are in increasing order.
p1 :: (Integer, Integer)
p1 = p1 -- bottom, infinite recursion
p2 :: (Integer, Integer)
p2 = (sum [1..], sum [1..]) -- not a bottom, but (_|_, _|_) which is only slightly larger
p3 :: (Integer, Integer)
p3 = (42, sum [1..])
-- (42, _|_) which is larger since it's more defined
-- (fewer bottoms inside, roughly speaking)
p4 :: (Integer, Integer)
p4 = (42, 23)
-- even larger, no larger values exist from here since it's a completely defined value
You can also make infinitely increasing sequences in some types:
l1 :: [Int]
l1 = l1 -- bottom
l2 :: [Int]
l2 = 1 : l1 -- not a bottom, 1 : _|_
l3 :: [Int]
l3 = 1 : 2 : l1 -- more defined, 1 : 2 : _|_
l4 :: [Int]
l4 = 1 : 2 : 432 : l1 -- more defined
-- etc. we can go on forever
This ordering of values is important in programming language theory because recursive definitions always find the least value satisfying the recursive equation.
E.g. the equation x1=x1 in Int is satisfied by _|_, 0, 1, -1, ..., but if we consider that it's a recursive definition, we have to take the least solution, namely _|_.
Similarly, in p :: (Integer, Integer) defined as p = (32, snd p), we find the solutions (32, _|_), (32, 0), (32, 1), (32, -1), .... but we need to take the least so we have (32, _|_). This models the fact that when we evaluate the expression the second component is never defined (because of infinite recursion).

Related

Why do I have to call `sum` twice to sum a list of `Maybe Integer`s?

I wrote a solution for a very simple practice problem:
Calculate the number of grains of wheat on a chessboard given that the number on each square doubles. Write code that shows how many grains are on a given square, and the total number of grains on the chessboard.
The function must return a Maybe Integer and return Nothing if the input is less than 1 or greater than 64.
square :: Integer -> Maybe Integer
square n = if (n < 1 || n > 64) then Nothing else Just (2^(pred n))
total :: Integer
total = sum (fmap sum (map square [1..64]))
I tried to apply fmap sum to some test output of map square (list of Maybe Integer) in GHCI and was surprised to discover it returns the list of integers (sans Just) rather than their sum. So in the solution above I apply sum a second time to actually get the sum.
I would like to understand conceptually why this is the case: in other words why is sum behaving like a converter for Maybe Ints to Ints in this context instead of adding things?
I've solved some similar exercises relying on helper functions to avoid complications of doing computation on Maybe values, and perhaps in this case I should just calculate the value of total without utilizing square, i.e.:
total = sum [2^n | n <- [0..63]]
However since I'd already written a useful function my first instinct was to reuse it, which led to some unforeseen behavior.
Let's look at the type of sum:
sum :: (Foldable t, Num a) => t a -> a
Often, for a beginner, this is simplified by assuming that t ~ [], so that we instead use sum as
sum :: Num a => [a] -> a
If we try to use sum at this type in your example, we will get a type error, because you have a list of Maybe numbers, not a list of numbers. Instead you write fmap sum [Just 1], specializing sum and fmap to:
sum :: Maybe Integer -> Integer
fmap :: (Maybe Integer -> Integer) -> [Maybe Integer] -> [Integer]
So the question isn't really "why isn't sum adding things", so much as "how can sum have a meaningful definition when given a single Maybe Integer?"
One way to answer that question, if you're not familiar with how to interpret sum as working on Foldable or how Maybe is foldable, is to just try implementing it yourself. There's really only one reasonable implementation:
sum :: Maybe Integer -> Integer
sum Nothing = 0
sum (Just x) = x
Right? Someone asked you "what's the total of the numbers in here", and then gave you either zero or one number. Pretty easy to add up. That's exactly how sum works for Maybe, except that it goes through Foldable instead of being specialized to Maybe.
After this, of course it's easy: you've turned your [Maybe Integer] into an [Integer], and of course summing that gets you the sum of the non-Nothing entries.
Let's look at an example.
map square [0..2] = [Nothing, Just 1, Just 2]
fmap sum (map square [0..2]) = [sum Nothing, sum (Just 1), sum (Just 2)]
Since Maybe is a Foldable container, it makes sense to calculate the sum of its elements:
sum Nothing = 0
sum (Just a) = a
So
fmap sum (map square [0..2]) = [0, 1, 2]
Now I don't know what you were actually hoping to do with the Maybes, but this is why you got what you got.
One thing worth internalising; when you map a function over a list1, the result is always going to be a list with the same number of elements. The function will be applied to each element of the list individually; it cannot combine them into a single summary value. That's just not what fmap does.
So with that principle in mind, we know that fmap sum squares (where squares = map square [1..64]) cannot possibly result in the sum of squares. It's going to be [ sum (square 1), sum (square 2), ... , sum (square 64) ]. We will then need to apply sum again to that whole list, if we want to actually add them up.
That just leaves an explanation for what sum (square 1) etc is actually doing (i.e. what sum does when applied to Maybe values). The proper type for sum is sum :: (Foldable t, Num a) => t a -> a. Foldable is basically the type-class of structures that you can scan for 0 or more elements in order (essentially: those you can convert to a list). All sum does is add up the elements that are there, however many there are (and use 0 as a "starting value" in case there are no elements). Maybe has a Foldable instance; it always has 0 or 1 elements, and sum can add those up just as well as it can add up lists that happen to have only 0 or 1 elements.
Of course the effect of summing zero-or-one numbers is just that the result is 0 if there were zero inputs and equal the input number if there was one. + never actually gets called for this "sum", which makes it feel a little pointless. But sum didn't know that; it works for any Foldable, regardless of how many elements they contain. And Maybe didn't know that it would end up being used to "sum without actually adding"; it just implemented Foldable so that any other function that wants to scan a variable number of elements out of a structure can scan Maybes.
If you think it's silly, just don't use sum for that job; use fromMaybe 0 instead.
1 You can generalise this to other functors beyond lists; when you fmap a function over a data structure, the result will have exactly the same structure as the input. Only the "leaf nodes" will be different.
First of all, the fmap in
total = sum (fmap sum (map square [1..64]))
is just map:
total = sum ( map sum (map square [1..64]))
and the maps compose by composing their mapping functions,
total = sum ( map (sum . square) [1..64] )
and a map applies its function to each element of the list,
total = sum [sum (square x) | x <- [1..64] ]
while a composed function finds its result in steps,
total = sum [sum y | x <- [1..64], y <- [square x] ]
whereas the inner sum is working with the result of square, namely, a Maybe number,
total = sum [ n | x <- [1..64], Just n <- [square x] ]
= sum [ n | x <- [1..64], Just n <- list (square x) ]
where list y = [y]
and turning sum y into just n works because sum finds a sum and 0 is its identity, so adding a 0 is the same as not adding anything at all. Meaning, the Just n pattern match fails when square produces a Nothing (which in our case is never, but never mind that) so that x which causes it is skipped over.
total = sum [ n | x <- [1..64], n <- maybeToList (square x) ]
= sum [ n | x <- [1..64], n <- case (square x) of
Just n -> [n]
Nothing -> [] ]
But again, we know that this never happens, and all this repackaging of the same number is all for naught, so in the end your code is equivalent to
total = sum [ n | x <- [1..64], Just n <- [Just (2^(x-1))] ]
= sum [ n | x <- [1..64], n <- [ 2^(x-1) ] ]
= sum [ 2^(x-1) | x <- [1..64] ]
just as you intended.
Seeing is better than believing (well, remembering / imagining, which is needed when using higher order functions ... unless of course one has an eidetic memory so for them believing is seeing). It might even give us new ideas for further code simplification, some transformations, and, eventually, maybe even some computational optimizations:
total = sum [ 2^x | x <- [0..63] ]
= sum [ product (replicate x 2) | x <- [0..63] ]
= sum $ [ product (replicate 0 2) ]
++ [ product (replicate x 2) | x <- [1..63] ]
= sum $ [ product [] ]
++ [ 2 * product (replicate (x-1) 2) | x <- [1..63] ]
= sum $ [ 1 ]
++ [ 2 * product (replicate x 2) | x <- [0..62] ]
= sum [1] + sum ( [2*n0] ++
[ 2 * product (replicate x 2) | x <- [1..62] ] )
where { n0=1 }
= n0 + sum [n1] + sum( [2*n1] ++
[ 2 * product (replicate x 2) | x <- [2..62] ] )
where { n0=1 ; n1=2*n0 }
= n0 + n1 + n2 + sum( [2*n2] ++
[ 2 * product (replicate x 2) | x <- [3..62] ] )
where { n0=1 ; n1=2*n0 ; n2=2*n1 }
= ....
= sum . take 64 $ iterate (2*) 1
And there they are again, the 64 squares of the chess board, and the first single grain of rice, which is doubled, and doubled again, as we ago along the squares.

Can a guard have more than one result?

As a newbie to Haskell, thinking in a way that's idiomatic is a challenge. I have a list of dyads. I want to weight dyad members according to two maps, one indicating the direction of the weighting and the other providing the weighting itself. In the following code 1 indicates that the bottom member of the dyad receives the weight; -1 the top member of the dyad receives the weight; 0 that both members receive the weight. In all cases it is the difference between dyad members that determines the weight and direction
My question is how can I re-use the definitions for top and bottom weight allocation in the case where the weighting is equal? Every source I have consulted so far seems to indicate that guards can have only one outcome - which I suspect is the proper Haskell way...
allocateWeight :: [[Integer]] -> (Integer, Integer, Maybe Double)
allocateWeight [x, y]
|direction <= Just 1 = assignBottom
|direction <= Just (-1) = assignTop
|direction <= Just 0 = (?? assignBottom and assignTop ??)
where diff = (abs(x!!1 - y!!1))
direction = Map.lookup diff getWeightDirection
weight = Map.lookup diff schemaCAT
assignBottom = (head x, last x, weight)
assignTop = (head y, last y, weight)
Okay Ive been asked to clarify further. Ill cut the non essentials as they will only cloud the issue.
Stage 1: start with a list of values eg: [6, 3, 8, 11, 2] : values constrained between 1 and 12.
Stage 2: permutate them into dyads: [(6,3),(6,8), (6,11), (6,2), (3, 8), (3, 11),(3, 2),(8, 11)(8, 2),(11,2)]
Stage 3: Get the absolute difference of each pair:[(3),(2),(5),(4),(5), (8), (1), (3), (6),(9)]
Stage 4: According to the difference between them ONE member of each dyad (with 6 being the exception) will receive a weighting; this is pre-determined in the following map:
getWeightDiretion :: Map.Map Integer Integer -- determine weight direction
getWeightDirection = Map.fromList $
[(1, -1),
(2, -1),
(3, 1),
(4, 1),
(5, -1),
(6, 0),
(7, 1),
(8, -1),
(9, -1),
(10, 1),
(11, 1),
(12, 1))]
As stated if the value of map lookup is 1 weight goes to bottom; -1 to top. The problem is when looking up key is 6 when neither of the dyad members are weighted more than the other: that is, they receive weight equally. The weightings are also predetermined by looking keys up in this map:
schemaCAT :: Map.Map Integer Double --Cross-At-Tail weighting scheme
schemaCAT = Map.fromList $
[(12, 0.985),
(11, -0.7),
(10, 0.2),
(9, 0.4),
(8, 0.6),
(7, 0.9),
(6, 0.08),
(5, 0.8),
(4, 0.7),
(3, 0.5),
(2, 0.1),
(1, -0.8),
(999, 0.25)]
The input to the allocateWeights function is in the form [[(-1, 6), (0, 3)], [.... where the first member of each tuple in each sub-list is a transposing factor - which is not relevant here; the second is one of a permutation pair. Each sub-list in the input represents one permutation. The allocateWeights function operates on x!!1 of each tuple in each sub-list directly.
After applying the above I should end up with a list a tuples [(-1, 3, 0.5)....] The second tuple member is the member of the tuple that receives the weight and the third is the weight itself (I'll leave out what the first member of the tuple is as is not important. The same with key 999 which is a special case).
As far as I understand it I have two problems. First, maps return Maybes and using these values in guards is problematic, Second, is the issue of using two definitions on the right hand side of an expression in a guard. Still struggling with 'Justs' and 'Maybes' :(
THX....
I’m not sure how you intend to combine the results when you write “assignBottom and assignTop”, but I can offer a few suggestions that may help.
When you find yourself in a situation like this, with a tangle of primitive types that are frustrating to work with, it’s usually a sign that you’re trying to do too many things at once in a single function, and that you need to introduce auxiliary functions or data types and compose them to solve the problem. When I look at this code:
allocateWeight :: [[Integer]] -> (Integer, Integer, Maybe Double)
allocateWeight' [x, y]
|direction <= Just 1 = assignBottom
|direction <= Just (-1) = assignTop
|direction <= Just 0 = (?? assignBottom and assignTop ??)
where diff = (abs(x!!1 - y!!1))
direction = Map.lookup diff getWeightDirection
weight = Map.lookup diff schemaCAT
assignBottom = (head x, last x, weight)
assignTop = (head y, last y, weight)
What jumps out at me are the following:
Is it allocateWeight or allocateWeight'?
The input is [[Integer]], but you say that the inner lists are known to be “dyads”, so this list probably wants to be a list of pairs [(Integer, Integer)].
Furthermore, allocateWeight assumes that there are only two elements in the outer list with the pattern [x, y]. Is this function meant to operate on the whole list, or each pair in the list?
The result type (Integer, Integer, Maybe Double), doesn’t explain its meaning; it would benefit from being a data type.
A series of guards direction <= Just … suggests that you want to first pattern-match on the Maybe value and then compare its range.
Your guard values are overlapped. Guards are checked in order, Nothing compares less than Just x for any x, and Just x <= Just y if x <= y. So if the value isn’t found, Nothing will compare less than Just 1 and the first guard will be taken; and if the value compares less than or equal to Just (-1) or Just 0, then it must already have compared less than or equal to Just 1, so the other two guards will never fire.
diff = (abs(x!!1 - y!!1)) again suggests that these don’t want to be lists; the indexing operator !! is best avoided in ordinary code. (It does have some use in cases where, for example, you’re using a list for memoisation, but that’s for another time.)
The weight directions are always -1, 0, or 1, which is asking to be a data type.
The returned weight probably shouldn’t be wrapped in a Maybe.
So just in terms of code organisation, here’s how I would approach this:
-- A pair of a value with a weight.
data Weighted a = Weighted a Double
deriving (Show)
-- The direction in which to weight a pair.
data WeightDirection
= WeightBottom
| WeightTop
| WeightBoth
-- Use data type instead of integer+comment.
getWeightDirection :: Map.Map Integer WeightDirection
getWeightDirection = Map.fromList
[ (1, WeightTop)
, (2, WeightTop)
, (3, WeightBottom)
, (4, WeightBottom)
, (5, WeightTop)
, (6, WeightBoth)
-- …
]
-- Allocate weights for a single pair.
allocateWeight :: (Integer, Integer) -> [Weighted Integer]
allocateWeight (x, y) = case Map.lookup diff getWeightDirection of
Just direction -> case Map.lookup diff schemaCAT of
Just weight -> case direction of
WeightBottom -> [Weighted x weight]
WeightTop -> [Weighted y weight]
WeightBoth -> [Weighted x weight, Weighted y weight]
-- What do you want to do in this case?
Nothing -> error ("direction for " ++ show diff ++ " not found")
-- What do you want to do if the difference isn’t found?
-- Raise an error like this, or return a default?
Nothing -> error ("weight for " ++ show diff ++ " not found")
where
diff = abs (x - y)
I’ve guessed that when you want to allocate weight “equally” to both values, that you want to include both values in the result, each with their own weight, so I’ve changed allocateWeight to return a list. If you want to combine the weights in a different way, say, (x * weight / 2 + y * weight / 2) or something like that, then you may not need that. Using lists, as to your particular question, you could also write: bottom = [Weighted x weight] and top = [Weighted y weight], and then return bottom, top, or their concatenation bottom ++ top as needed.
But this illustrates what I want to show: with this function for operating on a single pair, you can compute the results for a whole list of pairs by mapping it over the input list and concatenating the results, using those functions separately or using concatMap:
allocateWeight :: (Integer, Integer) -> [Weighted Integer]
map allocateWeight :: [(Integer, Integer)] -> [[Weighted Integer]]
concatMap allocateWeight :: [(Integer, Integer)] -> [Weighted Integer]
You may be asking: what happened to the “extra” values you were keeping alongside each pair? The answer is that this function shouldn’t be concerned with them; generally the approaches are to extract the portions you need (with map or similar) and recombine the results (e.g. using zipWith prior to concat), or parameterise this function so it can only see the portions of a value that it needs, e.g.:
allocateWeightBy :: (a -> Integer) -> (a, a) -> [Weighted a]
allocateWeightBy getValue (x, y) = …
-- Since ‘x’ has a polymorphic type, it enforces that
-- the only thing you can do with it is call ‘getValue’
-- or return it in the list of weighted values.
The other thing is that if you’re struggling with Maybe results from looking up keys that may not be present in a Map, you may just need practice, but you could also benefit from trying different approaches, like:
Use case wherever you have a lookup to explicitly handle the absence of a value. It’s verbose but it works and can be made more idiomatic later.
If the Nothing case should raise an error, use the unsafe indexing operator (Data.Map.!). (Like !! this can be a sign of poor data structuring, and can bite you later.)
If you just want to provide a default value, use functions like fromMaybe found in Data.Maybe, e.g. fromMaybe (defaultWeight :: Double) (maybeWeight :: Maybe Double) :: Double.
Use a function instead of a Map, with a fallthrough case for a key that’s not found.

Unresolved top level overloading

Task is to find all two-valued numbers representable as the sum of the sqrt's of two natural numbers.
I try this:
func = [sqrt (x) + sqrt (y) | x <- [10..99], y <- [10..99], sqrt (x) `mod` 1 == 0, sqrt (y) `mod` 1 == 0]
Result:
Unresolved top-level overloading Binding : func
Outstanding context : (Integral b, Floating b)
How can I fix this?
This happens because of a conflict between these two types:
sqrt :: Floating a => a -> a
mod :: Integral a => a -> a -> a
Because you write mod (sqrt x) 1, and sqrt is constrained to return the same type as it takes, the compiler is left trying to find a type for x that simultaneously satisfies the Floating constraint of sqrt and the Integral constraint of mod. There are no types in the base library that satisfy both constraints.
A quick fix is to use mod' :: Real a => a -> a -> a:
import Data.Fixed
func = [sqrt (x) + sqrt (y) | x <- [10..99], y <- [10..99], sqrt (x) `mod'` 1 == 0, sqrt (y) `mod'` 1 == 0]
However, from the error you posted, it looks like you may not be using GHC, and mod' is probably a GHC-ism. In that case you could copy the definition (and the definition of the helper function div') from here.
But I recommend a more involved fix. The key observation is that if x = sqrt y, then x*x = y, so we can avoid calling sqrt at all. Instead of iterating over numbers and checking if they have a clean sqrt, we can iterate over square roots; their squares will definitely have clean square roots. A straightforward application of this refactoring might look like this:
sqrts = takeWhile (\n -> n*n <= 99)
. dropWhile (\n -> n*n < 10)
$ [0..]
func = [x + y | x <- sqrts, y <- sqrts]
Of course, func is a terrible name (it's not even a function!), and sqrts is a constant we could compute ourselves, and is so short we should probably just inline it. So we might then simplify to:
numberSums = [x + y | x <- [4..9], y <- [4..9]]
At this point, I would be wondering whether I really wanted to write this at all, preferring just
numberSums = [8..18]
which, unlike the previous iteration, doesn't have any duplicates. It has lost all of the explanatory power of why this is an interesting constant, though, so you would definitely want a comment.
-- sums of pairs of numbers, each of whose squares lies in the range [10..99]
numberSums = [8..18]
This would be my final version.
Also, although the above definitions were not parameterized by the range to search for perfect squares in, all the proposed refactorings can be applied when that is a parameter; I leave this as a good exercise for the reader to check that they have understood each change.

Calculating the "e" constant using Haskell's until function

I want to calculate the "e" constant using Haskell's (Prelude) built-in until function. I want to do something like this:
enumber = until (>2.7) iter (1 0)
iter x k = x + (1/(fact (k + 1)))
fact k = foldr (*) 1 [1..k]
When I try to run this code, I get this error:
Occurs check: cannot construct the infinite type: a ~ a -> a
Expected type: (a -> a) -> a -> a
Actual type: a -> a -> a
Relevant bindings include enumber :: a -> a (bound at Lab2.hs:65:1)
In the second argument of ‘until’, namely ‘iter’
In the expression: until (> 2.7) iter (1 0)
By "e" I mean e = 2.71828..
The concrete mistake that causes this error is the notation (1 0). This doesn't make any sense in Haskell, it is parsed such that 1 is a function which is applied to 0, and the result then used. You apparently mean to pass both 1 and 0 as (initial) arguments. That's what we have tuples for, written (1,0).
Now, before trying to make anything definitions, we should make clear what types we need and write them out. Always start with your type signatures, they guide you a lot to you the actual definitions should look!
enumber :: Double -- could also be a polymorphic number type, but let's keep it simple.
type Index = Double -- this should, perhaps, actually be an integer, but again for simlicity use only `Double`
fact :: Index -> Double
now, if you want to do something like enumber = until (>2.7) iter (1,0), then iter would need to both add up the series expansion, and increment the k index (until knows nothing about indices), i.e. something like
iter :: (Double, Index) -> (Double, Index)
But right now your iter has a signature more like
iter :: Double -> Index -> Double
i.e. it does not do the index-incrementing. Also, it's curried, i.e. doesn't accept the arguments as a tuple.
Let's try to work with a tuple signature:
iter :: (Double, Index) -> (Double, Index)
iter (x,k) = ( x + 1/(fact (k + 1)), k+1 )
If you want to use this with until, you have the problem that you're always working with tuples, not just with the accumulated results. You need to throw away the index, both in the termination condition and in the final result: this can easily be done with the fst function
enumber = fst $ until ((>2.7) . fst) iter (1,0)
Now, while this version of the code will type-check, it's neither elegant nor efficient nor accurate (being greater than 2.7 is hardly a meaningful condition here...). As chi remarks, a good way of summing up stuff is the scanl function.
Apart from avoiding to manually increment and pass around an index, you should also avoid calculating the entire factorial over and over again. Doing that is a pretty general code smell (there's a reason fact isn't defined in the standard libraries)
recipFacts :: [Double] -- Infinite list of reciprocal factorials, starting from 1/0!
recipFacts = go 1
where go k = 1 : map (/k) (go (k+1))
Incidentally, this can also be written as a scan: scanl (/) 1 [1..] (courtesy of Will Ness).
Next we can use scanl to calculate the partial sums, and use some termination condition. However, because the series converges so quickly, there's actually a hack that works fine and is even simpler:
enumber :: Double
enumber = sum $ takeWhile (>0) recipFacts
-- result: 2.7182818284590455
Here I've used the fact that the fast-growing factorial quickly causes the floating-point reciprocals to underflow to zero.
Of course, really there's not a need to sum anything up yourself at all here: the most to-the-point definition is
enumber = exp 1
and nothing else.
enumber = until (>2.7) iter (1 0)
-- ^^^^^
Above you are applying "function" 1 to argument 0. This can't work.
You may want to use a pair instead (1, 0). In that case, not that iter must be changed to accept and return a pair. Also, the predicate >2.7 must be adapted to pairs.
If you don't want to use pairs, you need a different approach. Look up the scanl function, which you can use to compute partial sums. Then, you can use dropWhile to discard partial sums until some good-enough predicate is satisfied.
An example: the first ten partial sums of n^2.
> take 10 $ scanl (+) 0 [ n^2 | n<-[1..] ]
[0,1,5,14,30,55,91,140,204,285]
Note that this approach works only if you compute all the list elements independently. If you want to reuse some computed value from one element to another, you need something else. E.g.
> take 10 $ snd $ mapAccumL (\(s,p) x -> ((s+p,p*2),s+p)) (0,1) [1..]
[1,3,7,15,31,63,127,255,511,1023]
Dissected:
mapAccumL (\(s,p) x -> ((s+p,p*2),s+p)) (0,1) [1..]
a b c d e
s previous sum
p previous power of two
x current element of [1..]
a next sum
b next power of two
c element in the generated list
d first sum
e first power of two
Still, I am not a big fan of mapAccumL. Using iterate and pairs looks nicer.

sum of squares of integers [duplicate]

This question already has answers here:
Sum of Squares using Haskell
(3 answers)
Closed 8 years ago.
Ok This is a homework question but I'm not asking for a solution to how its done
What I want to ask is what it is asking me to do?
The sum of the squares of integers in the range m:n (where m ≥ n) can
be computed recursively. If there is more than one number in the range
m:n, the solution is to add the square of m to the sum of the squares
in the rangem+1:n; otherwise there is only one number in the range
m:n, so m == n, and the solution is just the square of m.
a. Define the recursive function sumsquares to carry out this
computation. As always, draw up a series of test data showing the
expected output, and then test the function.
I know I have to write a recursive function called sumsquares but I dont quite understand what it means by "The sum of the squares of integers in the range m:n (where m ≥ n) can be computed recursively".
This is the code I have so far, Would this be correct??
sumsquares :: Integral a=> Int -> Int -> Int
sumsquares m n
|m > n = error "First number cannot be bigger than second number"
|m==n = m*n
|otherwise = m*n +sumsquares (m+1)n
Someone else came up with this answer
sumOfSquaresFast :: Integral a => a -> a -> a
sumOfSquaresFast lo hi
| lo > hi = error "sumOfSquaresFast: lo > hi"
| otherwise = ssq hi - ssq (lo - 1)
where ssq x = div (2 * x^3 + 3 * x^2 + x) 6
But I do not understand the bottom part, the ssq and the div functions?
From what I understand, you want to take two numbers, e.g. 1 and 10, square each number between them (inclusively), and then take the sum of that. So you'd want some function like
sumOfSquaresBetween :: Int -> Int -> Int
sumOfSquaresBetween m n = ???
Now, you have to use recursion, so this means that ??? is going to be some expression that uses sumOfSquaresBetween.
Now here's the trick: If you know sumOfSquares n n, then how would you find sumOfSquares (n - 1) n? What about sumOfSquares (n - 2) n? Can you generalize this all the way to sumOfSquares m n for m <= n? If so, then you've just performed your desired algorithm, but in reverse.
Hope this hint helps.
"The sum of the squares of integers in the range m:n (where m ≥n) can be computed recursively."
Let's break this apart....
"integers in the range m:n"
is the set of integers starting from m, going to n
[m, m+1, m+2, ....n]
ie-
integers in the range 4:8 = [4,5,6,7,8]
"squares of...."
As you probably know, the square of a number x is x*x, so
squares of integers in the range 4:8 = [16, 26, 36, 49, 64]
"The sum of...."
add them
The sum of the squares of integers in the range 4:8 = 16+26+36+49+64
".... can be computer recursively"
Well, you have to understand recursion to get this....
Any function that contains itself in the definition is recursive. Of course you have to be careful, if done incorrectly, a recursive function could lead to infinite loops....
For Ints, (N-1) recursion is common.... If you can use the calculation for (N-1) to evaluate the calculation for N, the computer can run down the numbers until a known value is hit (typically 0). This is better seen with an example.
let func n = sum of integers from 0 to n
(this is like your problem, but without the squares part)
if you know the value of func (n-1), you can easily compute the value of func n
func n = n + func (n-1)
func 0 = 0
The computer will use func 0 to compute func 1, func 1 to compute func 2, etc, all the way to N.
Recursion has two common (but actually pretty different) uses... First, as shown above, it allows for very clean function definitions.
Secondly, it is often used in mathematics to prove truths over all integers (ie- to prove something is true for all ints, prove it is true for 0, then prove if it is true for N, it is true for N+1....).
Really, the best way to solve this problem is also the easiest: use library functions.
sumsquares :: Integral a => a -> a -> a
sumsquares m n = sum (map (^2) (enumFromTo n m))
You just enumerate the numbers from n to m, square each of them, and take the sum of the results. Trying to solve this problem in with direct recursion just makes things needlessly complicated.
Exercise: Write your own versions of the library functions used in this answer.
-- | Generate the list of all values in the given range. Result is inclusive.
enumFromTo :: Enum a => a -> a -> [a]
-- | Apply a function individually to each element of the argument list,
-- and collect the results as a list, respecting the order of the original.
map :: (a -> b) -> [a] -> [b]
-- | Calculate the sum of a list of numbers.
sum :: Num a => [a] -> a

Resources