Skip to content

Instantly share code, notes, and snippets.

@dmalikov
Created December 18, 2011 11:16
Show Gist options
  • Save dmalikov/1493055 to your computer and use it in GitHub Desktop.
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)
@chamini2
Copy link

in line 22 you can use

   furry = (.)

and in the line 71 you can use

  unicorn = const

@ilyats
Copy link

ilyats commented Mar 26, 2015

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 = (=<<) )

@mucaho
Copy link

mucaho commented Jun 12, 2015

@ilyats

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment