twice :: (a->a) -> a -> a
twice = \ f x -> f (f x)
-- twice f = \ x -> f (f x)
-- twice f x = f (f x)
-- twice f x = (f . f) x
-- (->) vs (=>)
map' :: (a->b) -> [a] -> [b]
--map' f [] = []
--map' f (x:xs) = f x : map' f xs
map' f xs = [ f x | x <- xs]
filter' :: (a->Bool) -> [a] -> [a]
filter' f xs = [ x | x <- xs, f x]
sum' [] = 0
sum' (x:xs) = x + sum' xs
product' [] = 1
product' (x:xs) = x * product' xs
and' [] = True
and' (x:xs) = x && and' xs
myfoldr :: (a->b->b) -> b -> [a] -> b
myfoldr f v [] = v
myfoldr f v (x:xs) = x `f` myfoldr f v xs
mysum = myfoldr (+) 0
myprod = myfoldr (*) 1
mylength = myfoldr (\ _ b -> 1 + b) 0