To celebrate trying to learn Haskell for a few weeks now, I figured I’d do a quick rundown of 99 Haskell Problems, as I try to solve them^{1}.
I’ll try and post my ‘solutions’ as soon as it satisfies the problem definition; in that sense, I expect they’ll appear very crude to Haskell veterans but hey, when was that ever a showstopper? Here we go with problems 110:
 Problem 1: Find the last element of a list.
 First thought that came to mind was to recursively exhaust the list (from Erlang
 tutorial time):
mylast :: [a] > a
mylast [] = error "empty list"
mylast [x] = x
mylast (_:xs) = mylast xs
 Problem 2: Find the last but one element of a list:
lastbutone :: [a] > a
lastbutone [] = error "empty list"
lastbutone [x] = error "single element list"
lastbutone [x, _] = x
lastbutone (_:xs) = lastbutone xs
 Problem 3: Find the k'th element of a list. The first element in the list is number 1.
 It was somewhat surprising for me that counting wasn't exactly necessary for it:
elementAt :: [a] > Int > a
elementAt xs n = last (take n xs)
 Problem 4: Find the number of elements of a list. Recursive counting!
mylength :: [a] > Int
mylength [] = 0
mylength (_:xs) = 1 + mylength xs
 Problem 5: Reverse a list. Soon to appear in your job interviews:
myreverse :: [a] > [a]
myreverse [] = []
myreverse xs = myreverse (tail xs) ++ [head xs]
 Problem 6: Find out whether a list is a palindrome.
 Palindromes are easy, so here's the first interesting view at [type constraints](https://en.wikibooks.org/wiki/Haskell/Classes_and_types#Type_constraints).
 `(Eq a)` constraints `a` to instances of type `Eq`, informally meaning that the
 argument to isPalindrome is a list of things which support equality and inequality:
isPalindrome :: (Eq a) => [a] > Bool
isPalindrome [] = True
isPalindrome [_] = True
isPalindrome xs = (head xs) == (last xs) && (isPalindrome (init (tail xs)))
 Problem 7: Flatten a nested list structure:
 This is my first contact with type definitions. A nested list is quite simple to define
 recursively:
data NestedList a = Elem a  List [NestedList a]
myflatten :: NestedList a > [a]
myflatten (Elem x) = [x]
myflatten (List []) = []
 Then I will process it recursively as well:
myflatten (List (x:xs)) = myflatten x ++ myflatten (List xs)
 Problem 8: Eliminate consecutive duplicates of list elements:
compress :: (Eq a) => [a] > [a]
 The argument here might be a bit frightening at first. What I want is to refer to the
 first element of a list, and the "first of the rest". If the first (x) is equal to the
 first of the rest (y), then I can ignore it (x)  or consume it, if you will  and move
 onward to the rest of the list. The pattern match xs@(y:_) gives us that capability.
 Think of it as preserving only the last of consecutive duplicates in the list:
compress (x:xs@(y:_))
 x == y = compress xs
 otherwise = x : compress xs
compress xs = xs
 Problem 9: Pack consecutive duplicates of list elements into sublists. If a list
 contains repeated elements they should be placed in separate sublists:
pack :: (Eq a) => [a] > [[a]]
pack [] = []
 We split elements of a list recursively into those which are equal to the first one,
 and those that are not. Then do the same for the latter:
pack (x:xs) = let (first, rest) = span (==x) xs
in (x:first) : pack rest
 Problem 10: Runlength encoding of a list:
 This is incidentally, supereasy. Haskell has the `group` function, which is
 essentially `pack` from problem 9. All we need to do here is count the length of the
 sublists, and prepend it to a pair:
encode :: (Eq a) => [a] > [(Int, a)]
encode xs = map (\x > (length x, head x)) (group xs)

± a month ↩