Fix chapter 20

master
Gaël Depreeuw 6 years ago
parent 8945191a8c
commit ae9e3118df
  1. 19
      20-foldable/20.5-library-functions.md
  2. 4
      20-foldable/src/chapter.hs
  3. 30
      20-foldable/src/functions.hs

@ -1,2 +1,19 @@
# Exercises: Library Functions
# 20.5 Some basic derived operations
Why does `fmap length Just [1, 2, 3]` return 1?
```haskell
fmap :: Functor f => (a -> b) -> f a -> f b
length :: Foldable t => t a -> Int
Just :: a -> Maybe a
fmap length :: (Foldable t, Functor f) => f (t a) -> f Int
-- notice that the next argument given is an f (t a) and since
-- (->) is also a functor f is ((->) a) and (t a) is Maybe a
-- this also makes f Int an (a -> Int)
fmap length Just :: a -> Int
```
## Exercises: Library Functions
see src/functions.h

@ -10,7 +10,7 @@ data Constant a b = Constant b deriving (Eq, Show)
instance Foldable (Constant a) where
foldr f z (Constant b) = f b z
foldMap f (Constant b) = f b
-- 1' Mistake in book, probably meant:
-- 1' Mistake in book as (1) is just Identity with shadow a, probably meant:
data Constant' a b = Constant' a deriving (Eq, Show)
instance Foldable (Constant' a) where
foldr _ z _ = z
@ -47,4 +47,4 @@ filterF f = foldr (\a b -> if f a then pure a `mappend` b else b) mempty
filterF' :: (Applicative f, Foldable t, Monoid (f a))
=> (a -> Bool) -> t a -> f a
filterF' f = foldMap (\a -> if f a then pure a else mempty)
filterF' f = foldMap (\a -> if f a then pure a else mempty)

@ -1,6 +1,7 @@
module Functions where
import Data.Monoid
import Data.Maybe
-- foldMap :: (Monoid m, Foldable t) => (a -> m) -> t a -> m
-- foldr :: Foldable t => (a -> b -> b) -> b -> t a -> b
@ -18,11 +19,21 @@ elem' :: (Foldable t, Eq a) => a -> t a -> Bool
elem' e = getAny . (foldMap (Any . (==e)))
minimum' :: (Foldable t, Ord a) => t a -> Maybe a
minimum' = foldr (\a b ->
minimum' = foldr (\a b ->
case b of
Nothing -> Just a
Just a' -> Just $ min a a')
Nothing
-- -- In order to use foldMap we need a monoid instance for smallest value
-- data Smallest a = Smallest { getSmallest :: Maybe a }
-- instance Ord a => Monoid (Smallest a) where
-- mempty = Smallest Nothing
-- mappend (Smallest Nothing) m = m
-- mappend m (Smallest Nothing) = m
-- mappend (Smallest (Just a1)) (Smallest (Just a2)) =
-- Smallest $ Just (min a1 a2)
-- minimum' = getSmallest . foldMap (Smallest . Just)
maximum' :: (Foldable t, Ord a) => t a -> Maybe a
maximum' = foldr (\a b ->
@ -30,20 +41,35 @@ maximum' = foldr (\a b ->
Nothing -> Just a
Just a' -> Just $ max a a')
Nothing
-- In order to use foldMap we need a monoid instance for largest value
-- data Largest a = Largest { getLargest :: Maybe a }
-- instance Ord a => Monoid (Largest a) where
-- mempty = Largest Nothing
-- mappend (Largest Nothing) m = m
-- mappend m (Largest Nothing) = m
-- mappend (Largest (Just a1)) (Largest (Just a2)) =
-- Largest $ Just (max a1 a2)
-- maximum' = getLargest . foldMap (Largest . Just)
null' :: Foldable t => t a -> Bool
null' = foldr (\_ _ -> False) True
-- Not very pretty, but it works:
-- null' = isNothing . getFirst . foldMap (First . Just)
length' :: Foldable t => t a -> Int
length' = foldr (\_ b -> b + 1) 0
-- length' = getSum . foldMap (Sum . const 1)
toList' :: Foldable t => t a -> [a]
toList' = foldr (:) []
-- toList' = foldMap (:[])
fold' :: (Foldable t, Monoid m) => t m -> m
-- fold' = foldMap (mappend mempty) -- mappend mempty = id
fold' = foldMap id
-- fold' = foldr mappend mempty
foldMap' :: (Foldable t, Monoid m) => (a -> m) -> t a -> m
-- foldMap' f = foldr (\a b -> mappend (f a) b) mempty
foldMap' f = foldr (mappend . f) mempty
foldMap' f = foldr (mappend . f) mempty

Loading…
Cancel
Save