20 Intermediate Haskell Exercises

18 09 2008
class Fluffy f where
  furry :: (a -> b) -> f a -> f b

-- Exercise 1
-- Relative Difficulty: 1
instance Fluffy [] where
  furry = error "todo"

-- Exercise 2
-- Relative Difficulty: 1
instance Fluffy Maybe where
  furry = error "todo"

-- Exercise 3
-- Relative Difficulty: 5
instance Fluffy ((->) t) where
  furry = error "todo"

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 = error "todo"

-- Exercise 5
-- Relative Difficulty: 5
instance Fluffy (EitherRight t) where
  furry = error "todo"

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' = error "todo"

-- Exercise 7
-- Relative Difficulty: 2
instance Misty [] where
  banana = error "todo"
  unicorn = error "todo"

-- Exercise 8
-- Relative Difficulty: 2
instance Misty Maybe where
  banana = error "todo"
  unicorn = error "todo"

-- Exercise 9
-- Relative Difficulty: 6
instance Misty ((->) t) where
  banana = error "todo"
  unicorn = error "todo"

-- Exercise 10
-- Relative Difficulty: 6
instance Misty (EitherLeft t) where
  banana = error "todo"
  unicorn = error "todo"

-- Exercise 11
-- Relative Difficulty: 6
instance Misty (EitherRight t) where
  banana = error "todo"
  unicorn = error "todo"

-- Exercise 12
-- Relative Difficulty: 3
jellybean :: (Misty m) => m (m a) -> m a
jellybean = error "todo"

-- Exercise 13
-- Relative Difficulty: 6
apple :: (Misty m) => m a -> m (a -> b) -> m b
apple = error "todo"

-- Exercise 14
-- Relative Difficulty: 6
moppy :: (Misty m) => [a] -> (a -> m b) -> m [b]
moppy = error "todo"

-- Exercise 15
-- Relative Difficulty: 6
-- (bonus: use moppy)
sausage :: (Misty m) => [m a] -> m [a]
sausage = error "todo"

-- Exercise 16
-- Relative Difficulty: 6
-- (bonus: use apple + furry')
banana2 :: (Misty m) => (a -> b -> c) -> m a -> m b -> m c
banana2 = error "todo"

-- 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 = error "todo"

-- 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 = error "todo"

newtype State s a = State {
  state :: (s -> (s, a))
}

-- Exercise 19
-- Relative Difficulty: 9
instance Fluffy (State s) where
  furry = error "todo"

-- Exercise 20
-- Relative Difficulty: 10
instance Misty (State s) where
  banana = error "todo"
  unicorn = error "todo"

Actions

Information

13 responses

19 09 2008
Chii

what exactly is it that you are asking in the exercise?

19 09 2008
Tony Morris

Replace the error values with a non-bottom implementation. Certain laws must satisfy on each implementation, but let’s leave that aside for now.

19 09 2008
James

Hi, I found your blog on this new directory of WordPress Blogs at blackhatbootcamp.com/listofwordpressblogs. I dont know how your blog came up, must have been a typo, i duno. Anyways, I just clicked it and here I am. Your blog looks good. Have a nice day. James.

19 09 2008
Arnaud Bailly

Hello,
Can we use Hoogle to guess the structures that are hidden behind Misty and Fluffy ;-) ?

Regards,
Arnaud

20 09 2008
rog

thanks. i enjoyed those, although the “relative difficulty” didn’t predict to any degree how long i took to complete each one. FWIW the one that took me longest was probably no. 12, and then things sped up as i struck my forehead and realised that Misty was Monad. no. 16 was probably second longest (getting the bonus), and some (e.g. 17 and 18) were very quick as almost identical to previous ones. the final “harder” ones were not too hard at all, probably because they felt a bit more “concrete”.

all quite useful for someone trying to get up to speed on this haskell stuff, i.e. me!

20 09 2008
Daniel Waechter

Some unit tests would be handy to check our work. Just a thought.

21 09 2008
BMeph

So, how much of the Prelude are we supposed to ignore? Some of the implementations get to simple, otherwise…

21 09 2008
Tony Morris

None. If it is too simple, then great.

22 09 2008
Dudeinator

These are great. Helped me familiarize myself with some of the standard libraries, and I had fun at the same time. After I finished each one I compared my implementation to the one in the standard libraries and of course it was almost always simpler, and some times perplexing.

22 09 2008
rog

daniel: i may be wrong here, but i think the idea is to produce any solution that will type check. so if you get it through the compiler, you’ve done it! no execution of code necessary.

25 09 2008
25 09 2008
BMeph

These were fun. I found 13 (apple)’s definition the toughest one to do, and I’m still not sure if it doesn’t have a simpler definition than what I did. The same for the State s ones, 19 and 20. They look a little clunky, , but then, so does (State s a) itself. Don’t even get me started on following the Lefts and Rights for the Misty forms of (EitherLeft t) and (EitherRight t). Still, it was fun to try out – thanks! :)

18 07 2009
Michael Greenberg

I must say, the names were pretty distracting. But this is a fun exercise in type directed programming.

Leave a comment