I am working through UPenn CIS 194: Introduction to Haskell (Spring 2013). Since I am not able to take the course for real I am asking for CR (feedback) as it could be from teacher in that course.
HW4 - Higher-order programming - Full description
import Data.List
-- Exercise 1
-- Reimplement each of the following functions in a more idiomatic Haskell style
fun1 :: [Integer] -> Integer
fun1 [] = 1
fun1 (x:xs)
| even x = (x - 2) * fun1 xs
| otherwise = fun1 xs
fun1' :: [Integer] -> Integer
fun1' = product . map (\x -> x - 2) . filter even
fun2 :: Integer -> Integer
fun2 1 = 0
fun2 n | even n = n + fun2 (n `div` 2)
| otherwise = fun2 (3 * n + 1)
fun2' :: Integer -> Integer
fun2' = sum . filter even . takeWhile (\x -> x > 1) . iterate (\x -> if (even x) then div x 2 else 3 * x + 1)
-- Exercise 2
-- Generates a balanced binary tree from a list of values using foldr
data Tree a = Leaf
| Node Integer (Tree a) a (Tree a)
deriving (Show, Eq)
foldTree :: [a] -> Tree a
foldTree = foldr makeTree Leaf
makeTree :: a -> Tree a -> Tree a
makeTree a Leaf = Node 0 Leaf a Leaf
makeTree a (Node h l m r)
| height l <= height r = Node (height (makeTree a l) + 1) (makeTree a l) m r
| otherwise = Node (height (makeTree a r) + 1) l m (makeTree a r)
where
height Leaf = -1
height (Node h _ _ _) = h
-- Exercise 3
-- More folds:
-- implement a function which returns True if and only if there are a odd number of True values contained in the input list
xor :: [Bool] -> Bool
xor = odd . foldr (\x s -> if (x) then 1 + s else s) 0
-- map’ should behave identically to the standard map function
map' :: (a -> b) -> [a] -> [b]
map' f = foldr (\x xs -> (f x) : xs) []
-- implement foldl using foldr
myFoldl :: (a -> b -> a) -> a -> [b] -> a
myFoldl f base xs = foldr (\x s -> f s x) base (reverse xs)
-- Exercise 4
-- Implement the Sieve of Sundaram algorithm using function composition
sieveSundaram :: Integer -> [Integer]
sieveSundaram n = map (\x -> 2 * x + 1) (genSieve n)
where
valid x = (i <= j) && (i + j + 2 * i * j <= n) where (i, j) = x
genCrossed m = map (\(i, j) -> (i + j + 2 * i * j)) (filter valid (cartProd [1..m] [1..m]))
genSieve n = (\\) [1..n] (genCrossed n)
cartProd :: [a] -> [b] -> [(a, b)]
cartProd xs ys = [(x,y) | x <- xs, y <- ys]