Fix chapter 18

master
Gaël Depreeuw 6 years ago
parent bc90acc41f
commit cc9c0bcfd8
  1. 2
      18-monad/src/bind.hs
  2. 7
      18-monad/src/examples.hs
  3. 2
      18-monad/src/functions.hs
  4. 35
      18-monad/src/instances.hs

@ -3,4 +3,4 @@ module Bind where
import Control.Monad (join) import Control.Monad (join)
bind :: Monad m => (a -> m b) -> m a -> m b bind :: Monad m => (a -> m b) -> m a -> m b
bind = join . fmap f bind f = join . fmap f

@ -1,6 +1,7 @@
module Examples where module Examples where
import Control.Monad (join) import Control.Monad (join)
import Control.Applicative (liftA3)
twiceWhenEven :: [Integer] -> [Integer] twiceWhenEven :: [Integer] -> [Integer]
twiceWhenEven xs = do twiceWhenEven xs = do
@ -120,5 +121,7 @@ doSomething' n = do
pure (a, b, c) pure (a, b, c)
doSomething'' :: Integer -> Maybe (Integer, Integer, String) doSomething'' :: Integer -> Maybe (Integer, Integer, String)
doSomething'' n = doSomething'' n = liftA3 (,,) a b c
(pure g) <*> (f n) where a = f n
b = join $ pure g <*> a -- need join here...
c = join $ pure h <*> b -- need join here...

@ -10,7 +10,7 @@ l1 :: Monad m => (a -> b) -> m a -> m b
l1 f x = do l1 f x = do
a' <- x a' <- x
return $ f a' return $ f a'
l1 f x = x >>= (return . f) -- l1 f x = x >>= (return . f)
-- with fmap :) -- with fmap :)
-- l1 = fmap -- l1 = fmap

@ -4,7 +4,6 @@ import Test.QuickCheck
import Test.QuickCheck.Checkers import Test.QuickCheck.Checkers
import Test.QuickCheck.Classes import Test.QuickCheck.Classes
-- import Control.Monad (join)
import Control.Applicative (liftA2) import Control.Applicative (liftA2)
-- 1 -- 1
@ -74,9 +73,7 @@ instance Monoid (List a) where
mappend Nil l = l mappend Nil l = l
mappend (Cons a l) l' = Cons a (mappend l l') mappend (Cons a l) l' = Cons a (mappend l l')
instance Applicative List where instance Applicative List where
{-# INLINE pure #-}
pure = flip Cons Nil pure = flip Cons Nil
{-# INLINE (<*>) #-}
Nil <*> _ = Nil Nil <*> _ = Nil
_ <*> Nil = Nil _ <*> Nil = Nil
(Cons f fl) <*> as = (fmap f as) `mappend` (fl <*> as) (Cons f fl) <*> as = (fmap f as) `mappend` (fl <*> as)
@ -85,32 +82,8 @@ instance Monad List where
Nil >>= _ = Nil Nil >>= _ = Nil
(Cons a l) >>= k = (k a) `mappend` (l >>= k) (Cons a l) >>= k = (k a) `mappend` (l >>= k)
-- I originally had the above, because I thought that you could not -- The following is needed to get an Arbitrary for the List. I got the idea
-- use join, but I found a solution online that uses join. Trying to -- from looking at how it is done for []. It's not very efficient though.
-- understand:
-- join is defined as (join x = x >>= id)
-- You might think, wait a minute? id is (a -> a) and thus doesn't fit the
-- bill of (a -> m b), but let's look at things more closely
--
-- (>>=) :: m a -> (a -> m b) -> m b
-- a here is the type of x :: (m a')
-- b here is the inner type of x :: a',
-- updating gives us:
-- (>>=) :: m (m a') -> (m a' -> m a') -> m a'
-- and we see that we can pass the id function to it
-- This turns the >>= definition into a recursive one where the second time
-- the function is the id, which will join it all
-- unfortunately this crashes when testing the monad laws ... Why?
-- because this never ends... You get
-- fmap id (fmap id (... (fmap id (fmap f as))))
-- as >>= f = join $ fmap f as
-- toList :: [a] -> List a
-- toList [] = Nil
-- toList (x:xs) = Cons x $ toList xs
replicateM' :: Applicative m => Int -> m a -> m (List a) replicateM' :: Applicative m => Int -> m a -> m (List a)
replicateM' cnt0 f = loop cnt0 replicateM' cnt0 f = loop cnt0
where loop cnt where loop cnt
@ -122,7 +95,9 @@ listOf' gen = sized $ \n ->
do k <- choose (0,n) do k <- choose (0,n)
replicateM' k gen replicateM' k gen
-- toList :: [a] -> List a
-- toList [] = Nil
-- toList (x:xs) = Cons x $ toList xs
instance Arbitrary a => Arbitrary (List a) where instance Arbitrary a => Arbitrary (List a) where
arbitrary = listOf' arbitrary arbitrary = listOf' arbitrary
-- arbitrary = fmap toList (listOf arbitrary) -- arbitrary = fmap toList (listOf arbitrary)

Loading…
Cancel
Save