Learning Haskell maps, folds, loops and recursion - haskell

I've only just dipped my toe in the world of Haskell as part of my journey of programming enlightenment (moving on from, procedural to OOP to concurrent to now functional).
I've been trying an online Haskell Evaluator.
However I'm now stuck on a problem:
Create a simple function that gives the total sum of an array of numbers.
In a procedural language this for me is easy enough (using recursion) (c#) :
private int sum(ArrayList x, int i)
{
if (!(x.Count < i + 1)) {
int t = 0;
t = x.Item(i);
t = sum(x, i + 1) + t;
return t;
}
}
All very fine however my failed attempt at Haskell was thus:
let sum x = x+sum in map sum [1..10]
this resulted in the following error (from that above mentioned website):
Occurs check: cannot construct the infinite type: a = a -> t
Please bear in mind I've only used Haskell for the last 30 minutes!
I'm not looking simply for an answer but a more explanation of it.

I'm not looking simply for an answer but a more explanation of it.
On the left-hand side of the = you use sum as a function applied to x. The compiler doesn't know the type of x, so the compiler uses type variable a to stand for "the type of x." At thus point the compiler doesn't know the result type of the function sum either, so it picks another type variable, this type t, to stand for the result type. Now on the left-hand side the compiler thinks that the type of x is a -> t (function accepting a and returning t).
On the right-hand side of the = you add x and sum. In Haskell all kinds of numbers can be added, but you can add two numbers only if they have the same type. So here the compiler assumes that sum has the same type as x, namely type a.
But in Haskell an identifier has one type—maybe a whangdilly complicated type, but one type nevertheless. This includes sum, whose type should be the same on both sides of the ` sign, so the compiler tries to solve the equation
a = a -> t
There are no values for a and t that solve this equation. It simply can't be done. There is no a such that a is equal to a function that accepts itself as an argument. Thus ariseth the error message
cannot construct the infinite type: a = a -> t
Even with all the explanation, it's not such a great error message, is it?
Welcome to Haskell :-)
P.S. You might enjoy trying "Helium, for learning Haskell", which gives much nicer error messages for beginners.

'sum' takes a list of values and reduces it to a single value. You can either write it as an explicit loop (remember that Haskell has no loop keywords, but uses recursion). Note how the definition has two parts, based on the shape of the list:
mysum [] = 0
mysum (x:xs) = x + mysum xs
Or more efficiently, in a tail-recursive style:
mysum xs = go 0 xs
where
go n [] = n
go n (x:xs) = go (n+x) xs
However, Haskell has a rich library of control structures that operate on lazy lists. In this case, reduction of a list to a single value can be done with a reduce function: a fold.
So mysum can be written as:
mysum xs = foldr (+) 0 xs
For example:
Prelude> foldr (+) 0 [1..10]
55
Your mistake was to use a map, which transforms a list, one element at a time, rather than a fold.
I'd suggest you start with an introduction to Haskell, perhaps "Programming in Haskell", to get a feel for the core concepts of functional programming. Other good introductory materials are described in this question.

You need to read a good tutorial, there are a number of big misunderstandings.
First I'm going to assume you mean lists and not arrays. Arrays exist in Haskell, but they aren't something you'd encounter at the beginner level. (Not to mention you're using [1..10] which is a list of the numbers 1 to 10).
The function you want is actually built in, and called sum, so we'll have to call our something else, new_sum:
new_sum [] = 0
new_sum (h:t) = h + (sum t)

Let's look at the first part of this:
let sum x = x+sum
What would the type of sum be in this case? It takes a number and returns a function that takes a number which returns a function that takes a number etc. if you had written it
let sum x = + x
you would have a function that takes a number and returns the function +x.
and
let sum = +
would return a function that takes two integers and adds them.
so now let's look at the second part.
in map sum [1..10]
map takes a function of one argument and applies it to every element of the list. There is no room to wedge an accumulator in there, so let's look at other list functions in particular foldl, foldr. both of these take a function of two arguments a list and a beginning value. The difference between foldl and foldr is on the side in which they start. l being left so 1 + 2 + 3 etc and r being right 10 + 9 + 8 etc.
let sum = (+) in foldl sum 0 [1..10]

Related

Use of folding in defining functions

I was introduced to the use of fold in defining function. I have an idea how that works but im not sure why one should do it. To me, it feels like just simplifying name of data type and data value ... Would be great if you can show me examples where it is significant to use fold.
data List a = Empty | (:-:) a (List a)
--Define elements
List a :: *
[] :: List a
(:) :: a -> List a -> List a
foldrList :: (a -> b -> b) -> b -> List a -> b
foldrList f e Empty = e
foldrList f e (x:-:xs) = f x (foldrList f e xs)
The idea of folding is a powerful one. The fold functions (foldr and foldl in the Haskell base library) come from a family of functions called Higher-Order Functions (for those who don't know - these are functions which take functions as parameters or return functions as their output).
This allows for greater code clarity as the intention of the program is more clearly expressed. A function written using fold functions strongly indicates that there is an intention to iterate over the list and apply a function repeatedly to obtain an output. Using the standard recursive method is fine for simple programs but when complexity increases it can become difficult to understand quickly what is happening.
Greater code re-use can be achieved with folding due to the nature of passing in a function as the parameter. If a program has some behaviour that is affected by the passing of a Boolean or enumeration value then this behaviour can be abstracted away into a separate function. The separate function can then be used as an argument to fold. This achieves greater flexibility and simplicity (as there are 2 simpler functions versus 1 more complex function).
Higher-Order Functions are also essential for Monads.
Credit to the comments for this question as well for being varied and informative.
Higher-order functions like foldr, foldl, map, zipWith, &c. capture common patterns of recursion so you can avoid writing manually recursive definitions. This makes your code higher-level and more readable: instead of having to step through the code and infer what a recursive function is doing, the programmer can reason about compositions of higher-level components.
For a somewhat extreme example, consider a manually recursive calculation of standard deviation:
standardDeviation numbers = step1 numbers
where
-- Calculate length and sum to obtain mean
step1 = loop 0 0
where
loop count sum (x : xs) = loop (count + 1) (sum + x) xs
loop count sum [] = step2 sum count numbers
-- Calculate squared differences with mean
step2 sum count = loop []
where
loop diffs (x : xs) = loop ((x - (sum / count)) ^ 2 : diffs) xs
loop diffs [] = step3 count diffs
-- Calculate final total and return square root
step3 count = loop 0
where
loop total (x : xs) = loop (total + x) xs
loop total [] = sqrt (total / count)
(To be fair, I went a little overboard by also inlining the summation, but this is roughly how it may typically be done in an imperative language—manually looping.)
Now consider a version using a composition of calls to standard functions, some of which are higher-order:
standardDeviation numbers -- The standard deviation
= sqrt -- is the square root
. mean -- of the mean
. map (^ 2) -- of the squares
. map (subtract -- of the differences
(mean numbers)) -- with the mean
$ numbers -- of the input numbers
where -- where
mean xs -- the mean
= sum xs -- is the sum
/ fromIntegral (length xs) -- over the length.
This more declarative code is also, I hope, much more readable—and without the heavy commenting, could be written neatly in two lines. It’s also much more obviously correct than the low-level recursive version.
Furthermore, sum, map, and length can all be implemented in terms of folds, as well as many other standard functions like product, and, or, concat, and so on. Folding is an extremely common operation on not only lists, but all kinds of containers (see the Foldable typeclass), because it captures the pattern of computing something incrementally from all elements of a container.
A final reason to use folds instead of manual recursion is performance: thanks to laziness and optimisations that GHC knows how to perform when you use fold-based functions, the compiler may fuse a series of folds (maps, &c.) together into a single loop at runtime.

The length of a list without the "length" function in Haskell

I want to see how long a list is, but without using the function length. I wrote this program and it does not work. Maybe you can tell me why? Thanks!
let y = 0
main = do
list (x:xs) = list (xs)
y++
list :: [Integer] -> Integer
list [] = y
Your program looks quite "imperative": you define a variable y, and then somehow write a do, that calls (?) the list function (?) that automagically seems to "return y" and then you want to increment y.
That's not how Haskell (and most functional and declarative) languages work:
in a declarative language, you define a variable only once, after the value is set, there is usually no way to alter its value,
in Haskell a do usually is used for monads, whereas the length is a pure function,
the let is a syntax construction to define a variable within the scope of an expression,
...
In order to program Haskell (or any functional language), you need to "think functional": think how you would solve the problem in a mathematical way using only functions.
In mathematics, you would say that the empty list [] clearly has length 0. Furthermore in case the list is not empty, there is a first element (the "head") and remaining elements (the "tail"). In that case the result is one plus the length of the tail. We can convert that in a mathematical expression, like:
Now we can easily translate that function into the following Haskell code:
ownLength :: [a] -> Int
ownLength [] = 0
ownLength (_:xs) = 1 + ownLength xs
Now in Haskell, one usually also uses accumulators in order to perform tail recursion: you pass a parameter through the recursive calls and each time you update the variable. When you reach the end of your recursion, you return - sometimes after some post-processing - the accumulator.
In this case the accumulator would be the so far seen length, so you could write:
ownLength :: [a] -> Int
ownLength = ownLength' 0
where ownLength' a [] = a
ownLength' a (_:xs) = ownLength' (a+1) xs
It looks you still think in an imperative way (not the functional way). For example:
you try to change the value of a "variable" (i.e. y++)
you try to use "global variable" (i.e. y) in the body of the list function
Here is the possible solution to your problem:
main = print $ my_length [1..10]
my_length :: [Integer] -> Integer
my_length [] = 0
my_length (_:xs) = 1 + my_length xs
You can also run this code here: http://ideone.com/mjUwL9.
Please also note that there is no need to require that your list consists of Integer values. In fact, you can create much more "agnostic" version of your function by using the following declaration:
my_length :: [a] -> Integer
Implementation of this function doesn't rely on the type of items from the list, thus you can use it for a list of any type. In contrast, you couldn't be that much liberal for, for example, my_sum function (a potential function that calculates the sum of elements from the given list). In this situation, you should define that your list consists of some numerical type items.
At the end, I'd like to suggest you a fantastic book about Haskell programming: http://learnyouahaskell.com/chapters.
Other answers have already beautifully explained the proper functional approach. It looks like an overkill but here is another way of implementing the length function by using only available higher order functions.
my_length :: [a] -> Integer
my_length = foldr (flip $ const . (+1)) 0
I've found this solution in Learn you a haskell.
length' xs = sum [1 | _ <- xs]
It replaces every element of the list with 1 and sums it up.
Probably the simplest way is to convert all elements to 1 and then to sum the new elements:
sum . map (const 1)
For added speed:
foldl' (+) 0 . map (const 1)

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.

Basic summation in Haskell

I'm practicing Haskell, and writing a summation function that takes in two numbers (upper and lower limits) and does the summation.
ie, summation 0 10 would return 55
I can get it mostly working, but having trouble figuring out how to get it using only two parameters.
Here is what I have so far:
summation :: Integer -> Integer -> Integer -> Integer
summation x y sum =
if (y<x) then
sum
else
summation x (y-1) (sum+y)
So this works fine, but I need to do summation 0 10 0 to get it working properly. I'm not sure how I can get this working with only two parameters in Haskell.
You wrap it.
summation :: Integer -> Integer -> Integer
summation x y = summation' x y 0
summation' :: Integer -> Integer -> Integer -> Integer
summation' x y sum =
if (y<x) then
sum
else
summation' x (y-1) (sum+y)
The quick answer:
One simple way would be to use the sum function from Data.List.
Then you could simply say:
summation x y = sum [x .. y]
This solution assumes that x is less than y, and you could fix this by saying:
summation x y = sum [min x y .. max x y]
Defining sum:
Since you are learning Haskell, it might be important to know how sum works, instead of just knowing it exists. For me, the biggest hurdle to get over initially was writing too many functions that already existed; especially since I didn't know how to write them effectively.
Hoogle is a great help in this regard: it's a search engine that allows you to seach for Haskell functions. It's a great thing for productivity, because you'll be able to spend time working on your problem, instead of producing poor rewrites of half of the prelude. It's also great for learning, because there are links to the source code of most of the functions on Hackage. The source code of the Prelude and other "fundamental" libraries such as Data.List is surprisingly accessible to a beginner, and will provide a lot of insight into how "the smart kids" do things.
The :browse command in GHCI is something that I found out about recently that I wish I'd discovered sooner.
Anyway, one way of defining sum is by using a fold:
sum xs y = foldl (+) 0 xs
Or the equivalent in "pointless" style:
sum = foldl (+) 0
I usually prefer the first formulation, but knowing how and why the second one works will help you a lot in your journey.
Further Reading:
You'll notice that I used the function foldl. This function "folds" an input list. To "master" functional programming, knowing how to fold is both one of the most basic and important concepts. A good resource to consult is the page on folds from the Haskell Wiki.
You could do it like Gauss did.
summation begin end
| end < begin = summation end begin
| otherwise = n * (2*a + (n-1)*d) `div` 2
where a = begin
d = 1
n = end - begin + 1
Code is a blatantly literal translation from http://mathcentral.uregina.ca/QQ/database/QQ.02.06/jo1.html (a little ways down that page: S = n[2a + (n-1)d]/2)

Adding the powers of numbers in haskell with foldl

I am being asked to make an haskell function that computes something like
1^2 + 2^2 + 3^2 ...
While I find it quite easy to implement with list comprehensions
sum [ k^2 | k <- [1..100]]
or maps
sum (map (\x -> x*x) [1..100])
I'm having some hard time getting how to achieve it with foldls.
If I am not wrong, one needs no less than 3 parameters in a recursive function to achieve a result with this:
The current position (1... up to n)
The current sum
Where to stop
Even if I define this function, it will still return a tuple, not a number (like I need it to!).
Could anyone be kind enough to give me some clues on what I may be missing?
Thanks
If you look at the definition of sum, it's just sum = foldl (+) 0. So if you replace sum with foldl (+) 0 in either of your solutions, you have a solution using foldl.
You can also get rid of the need for list comprehensions or map by using foldl with a function that adds the square of its second argument to its first argument.
I'm not sure where your considerations about recursive functions figure into this. If you're using foldl, you don't need to use recursion (except in so far that foldl is implemented using recursion).
However, you are wrong that a recursive function would need three arguments: A recursive functions summing the squares of each element in a list, would most straight-forwardly implemented by taking a list and adding the head of the list to the result of calling the function on the list's tail. The base case being squareSum [] = 0. This has nothing to with foldl, though.
The "current position" (actually the next item in the list, just like in your map and list comprehension versions) and where to stop are implicit in the list being folded over. The current sum is the "accumulator" parameter of the fold. So, fill in the blank:
foldl (\runningSum nextNumber -> ____) 0 [1..100]

Resources