Solutions to Haskell Problems 1-10
My solutions to the first 10 of the 99 Haskell Problems.
module Problem1_10 where
import Data.List
import Control.Arrow ((&&&))
{--
Solution to the first 10 of the 99 Haskell Problems
Found at https://wiki.haskell.org/99_questions/1_to_10
--}
-- Problem 1 - find last element of list
myLast :: [a] -> a
myLast = foldr1 (flip const)
-- Problem 2 - find last but one element of list
myButLast :: [a] -> a
myButLast = fst . myLast . (zipWith (,) <*> tail)
-- Problem 3 - find K'th element of list
-- This is a little overboard...
elementAt :: [a] -> Integer -> a
elementAt xs n = snd . head . filter ((==n) . fst) $ (zipWith (,) [1..] xs)
-- Problem 4 - find length of list
myLength :: [a] -> Int
myLength = foldl (\s x -> s+1) 0
-- Problem 5 - reverse a list
myReverse :: [a] -> [a]
myReverse = foldl' f []
where f xs x = x : xs
-- Problem 6 - Is a list a palindrome
isPalindrome :: Eq a => [a] -> Bool
isPalindrome = ((==) <*> reverse)
-- Problem 7 - flatten a nested list
data NestedList a = Elem a | List [NestedList a]
deriving (Eq,Show)
instance Foldable NestedList where
foldr f z (Elem a) = f a z
foldr f z (List []) = z
foldr f z (List ((Elem a):ls)) = f a $ foldr f z (List ls)
foldr f z (List ((List l):ls)) = foldr f z' (List l)
where z' = foldr f z (List ls)
flatten :: NestedList a -> [a]
flatten = foldr (:) []
testlist = (List [Elem 1, List [],List [Elem 2, List [Elem 3, Elem 4], List [],Elem 5]])
-- Problem 8 - eliminate consecutive duplicates in a list
compress :: Eq a => [a] -> [a]
compress = map head . group
-- Problem 9 - put consective duplicates into sublists
-- A home-grown version of group
-- Of all these 10 problems, this took the longest to solve. I knew
-- roughly what I wanted to do, but working it out
-- and satisfying the typechecker took a little experimentation.
pack :: Eq a => [a] -> [[a]]
pack [] = []
pack xs = (:) <$> takeWhile (==hd) <*> pack . dropWhile (==hd) $ xs
where hd = head xs
-- Problem 10 - run-length encoding of a list
-- E.g., "aabbbcddd" => [(2,'a'),(3,'b'),(1,'c'),(3,'d')]
encode :: Eq a => [a] -> [(Int,a)]
encode = map (length &&& head) . pack
Written on December 13, 2017