[<< wikibooks] Yet Another Haskell Tutorial/Language basics/Solutions
== Arithmetic ==
It binds more tightly; actually, function application binds
more tightly than anything else.  To see this, we can do something
like:

If multiplication bound more tightly, the result would have been 3.

== Pairs, Triples and More ==
Solution: snd (fst ((1,'a'),"foo")).  This is because first we
want to take the first half the tuple: (1,'a') and then out
of this we want to take the second half, yielding just 'a'.
If you tried fst (snd ((1,'a'),"foo")) you will have gotten a
type error.  This is because the application of snd will leave
you with fst "foo".  However, the string "foo" isn't a tuple,
so you cannot apply fst to it.

== Lists ==

=== Strings ===

=== Simple List Functions ===
Solution: map Char.isLower "aBCde"
Solution: length (filter Char.isLower "aBCde")
Solution: foldr max 0 [5,10,2,8,1].
You could also use foldl.  The foldr case is easier to explain: we replace each
cons with an application of max and the empty list with 0.
Thus, the inner-most application will take the maximum of 0 and the
last element of the list (if it exists).  Then, the next-most inner
application will return the maximum of whatever was the maximum
before and the second-to-last element.  This will continue on,
carrying to current maximum all the way back to the beginning of the
list.
In the foldl case, we can think of this as looking at each element
in the list in order.  We start off our "state" with 0.  We pull
off the first element and check to see if it's bigger than our
current state.  If it is, we replace our current state with that
number and the continue.  This happens for each element and thus
eventually returns the maximal element.

== Source Code Files ==

== Functions ==

=== Let Bindings ===

=== Infix ===

== Recursion ==
We can define a fibonacci function as:

fib 1 = 1
fib 2 = 1
fib n = fib (n-1) + fib (n-2)

We could also write it using explicit if statements, like:

fib n =
if n == 1 || n == 2
then 1
else fib (n-1) + fib (n-2)

Either is acceptable, but the first is perhaps more natural in Haskell.
We can define:

a
∗
b
=

{

−
(
a
∗
(
−
b
)
)

b
<
0

0

b
=
0

a

b
=
1

a
+
a
∗
(
b
−
1
)

otherwise

{\displaystyle a*b={\begin{cases}-(a*(-b))&b<0\\0&b=0\\a&b=1\\a+a*(b-1)&{\mbox{otherwise}}\\\end{cases}}}

And then type out code:

mult a 0 = 0
mult a 1 = a
mult a b =
if b < 0
then 0 - mult a (-b)
else a + mult a (b-1)

Note that it doesn't matter that of

a

{\displaystyle a}
and

b

{\displaystyle b}
we do the recursion
on.  We could just as well have defined it as:

mult 0 b = 0
mult 1 b = b
mult a b =
if a < 0
then 0 - mult (-a) b
else b + mult (a-1) b

We can define my_map as:

my_map f [] = []
my_map f (x:xs) = f x : my_map f xs

Recall that the my_map function is supposed to apply a function
f to every element in the list.  In the case that the list is
empty, there are no elements to apply the function to, so we just
return the empty list.
In the case that the list is non-empty, it is an element x
followed by a list xs.  Assuming we've already properly applied
my_map to xs, then all we're left to do is apply f to
x and then stick the results together.  This is exactly what the
second line does.

== Interactivity ==
The code below appears in Numbers.hs.  The only tricky parts are
the recursive calls in getNums and showFactorials.

module Main
where

import System.IO

main = do
nums <- getNums
putStrLn ("The sum is " ++ show (sum nums))
putStrLn ("The product is " ++ show (product nums))
showFactorials nums

getNums = do
putStrLn "Give me a number (or 0 to stop):"
num <- getLine
then return []
else do rest <- getNums

showFactorials []     = return ()
showFactorials (x:xs) = do
putStrLn (show x ++ " factorial is " ++
show (factorial x))
showFactorials xs

factorial 1 = 1
factorial n = n * factorial (n-1)

The idea for getNums is just as spelled out in the hint.  For
showFactorials, we consider first the recursive call.  Suppose we
have a list of numbers, the first of which is x.  First we print
out the string showing the factorial.  Then we print out the rest,
hence the recursive call.  But what should we do in the case of the
empty list?  Clearly we are done, so we don't need to do anything at
all, so we simply return ().
Note that this must be return () instead of just () because
if we simply wrote showFactorials [] = () then this wouldn't be
an IO action, as it needs to be.  For more clarification on this, you
should probably just keep reading the tutorial.