-
-
Save dmalikov/1493055 to your computer and use it in GitHub Desktop.
import Control.Arrow (second) | |
class Fluffy f where | |
furry :: (a -> b) -> f a -> f b | |
-- Exercise 1 | |
-- Relative Difficulty: 1 | |
instance Fluffy [] where | |
furry _ [] = [] | |
furry f xs = foldr ((:) . f) [] xs | |
-- Exercise 2 | |
-- Relative Difficulty: 1 | |
instance Fluffy Maybe where | |
furry _ Nothing = Nothing | |
furry f (Just a) = Just . f $ a | |
-- Exercise 3 | |
-- Relative Difficulty: 5 | |
instance Fluffy ((->) t) where | |
-- ((->) t) is equal to (t ->) | |
furry f g = f . g | |
-- Exercise 3.5 | |
-- | |
instance Fluffy (Either t) where | |
furry _ (Left a) = Left a | |
furry f (Right a) = Right . f $ a | |
newtype EitherLeft b a = EitherLeft (Either a b) | |
newtype EitherRight a b = EitherRight (Either a b) | |
-- Exercise 4 | |
-- Relative Difficulty: 5 | |
instance Fluffy (EitherLeft t) where | |
furry f (EitherLeft (Left x)) = EitherLeft . Left . f $ x | |
furry _ (EitherLeft (Right x)) = EitherLeft . Right $ x | |
-- Exercise 5 | |
-- Relative Difficulty: 5 | |
instance Fluffy (EitherRight t) where | |
furry _ (EitherRight (Left x)) = EitherRight . Left $ x | |
furry f (EitherRight (Right x)) = EitherRight . Right . f $ x | |
class Misty m where | |
banana :: (a -> m b) -> m a -> m b | |
unicorn :: a -> m a | |
-- Exercise 6 | |
-- Relative Difficulty: 3 | |
-- (use banana and/or unicorn) | |
furry' :: (a -> b) -> m a -> m b | |
furry' f = banana $ unicorn . f | |
-- Exercise 7 | |
-- Relative Difficulty: 2 | |
instance Misty [] where | |
banana = concatMap | |
unicorn = return | |
-- Exercise 8 | |
-- Relative Difficulty: 2 | |
instance Misty Maybe where | |
banana _ Nothing = Nothing | |
banana f (Just x) = f x | |
unicorn = return | |
-- Exercise 9 | |
-- Relative Difficulty: 6 | |
instance Misty ((->) t) where | |
banana x y z = (x $ y z) z | |
unicorn f _ = f | |
-- Exercise 9.5 | |
-- | |
instance Misty (Either t) where | |
banana _ (Left x) = Left x | |
banana f (Right x) = f x | |
unicorn = Right | |
-- Exercise 10 | |
-- Relative Difficulty: 6 | |
instance Misty (EitherLeft t) where | |
banana _ (EitherLeft (Right x)) = EitherLeft . Right $ x | |
banana f (EitherLeft (Left x)) = f x | |
unicorn = EitherLeft . Left | |
-- Exercise 11 | |
-- Relative Difficulty: 6 | |
instance Misty (EitherRight t) where | |
banana _ (EitherRight (Left x)) = EitherRight . Left $ x | |
banana f (EitherRight (Right x)) = f x | |
unicorn = EitherRight . Right | |
-- Exercise 12 | |
-- Relative Difficulty: 3 | |
jellybean :: (Misty m) => m (m a) -> m a | |
jellybean = banana id | |
-- Exercise 13 | |
-- Relative Difficulty: 6 | |
apple :: (Misty m) => m a -> m (a -> b) -> m b | |
apple = banana . flip furry' | |
-- Exercise 14 | |
-- Relative Difficulty: 6 | |
moppy :: (Misty m) => [a] -> (a -> m b) -> m [b] | |
moppy [] _ = unicorn [] | |
moppy (x:xs) f = banana2 (:) (f x) $ moppy xs f | |
-- Exercise 15 | |
-- Relative Difficulty: 6 | |
-- (bonus: use moppy) | |
sausage :: (Misty m) => [m a] -> m [a] | |
-- sausage [] = unicorn [] | |
-- sausage (x:xs) = banana (\h -> banana (\t -> unicorn (h:t)) (sausage xs)) x | |
sausage = flip moppy id | |
-- Exercise 16 | |
-- Relative Difficulty: 6 | |
-- (bonus: use apple + furry') | |
banana2 :: (Misty m) => (a -> b -> c) -> m a -> m b -> m c | |
-- banana2 f s t = apple t (furry' f s) | |
banana2 = ( flip apple . ) . furry' | |
-- Exercise 17 | |
-- Relative Difficulty: 6 | |
-- (bonus: use apple + banana2) | |
banana3 :: (Misty m) => (a -> b -> c -> d) -> m a -> m b -> m c -> m d | |
-- banana3 f s t q = apple q (banana2 f s t) | |
banana3 = ( ( flip apple . ) . ) . banana2 | |
-- Exercise 18 | |
-- Relative Difficulty: 6 | |
-- (bonus: use apple + banana3) | |
banana4 :: (Misty m) => (a -> b -> c -> d -> e) -> m a -> m b -> m c -> m d -> m e | |
-- banana4 f s t q w = apple w (banana3 f s t q) | |
banana4 = ( ( ( flip apple . ) . ) . ) . banana3 | |
newtype State s a = State { | |
state :: (s -> (s, a)) | |
} | |
-- Exercise 19 | |
-- Relative Difficulty: 9 | |
instance Fluffy (State s) where | |
furry f (State x) = State $ second f . x | |
-- Exercise 20 | |
-- Relative Difficulty: 10 | |
instance Misty (State s) where | |
banana f (State v) = State $ \x -> state ( f . snd . v $ x ) x | |
unicorn s = State $ \x -> (x, s) |
I think in your solutions to ex.20 the second action is applied to the initial state, while it has more sense to apply it to the state created by the first action. My solution to ex 20 is:
instance Misty (State s) where
banana f m = State{state = g} where
g s = (state (f a)) s' where
(s', a) = (state m) s
unicorn a = State{state = f} where
f s = (s, a)
also, where is function 'second' you use in ex.19 defined? ghci doesn't have it in prelude.
Your use or 'return' in ex.8 seems like cheating (you could as well write banana = (=<<) )
also, where is function 'second' you use in ex.19 defined
It's part of Data.Bifunctor
. Pretty handy when working with tuple pairs.
Scrap that, as shown by the import import Control.Arrow (second)
it's part of Control.Arrow
in line 22 you can use
and in the line 71 you can use