summaryrefslogtreecommitdiff
path: root/Haskell-book/25/Twinplicative/src/Twinplicative.hs
blob: f8840fa890f9a735da67c745859a61fb05933e04 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
{-# LANGUAGE InstanceSigs #-}
module Twinplicative where

newtype Identity a
      = Identity { runIdentity :: a }

instance Functor Identity where
      fmap f (Identity a) = Identity (f a)

newtype Compose f g a =
      Compose { getCompose :: f (g a) }
      deriving (Eq, Show)

instance (Functor f, Functor g) =>
          Functor (Compose f g) where
      fmap f (Compose fga) =
            Compose $ (fmap . fmap) f fga

-- instance types provided as they may help.
instance (Applicative f, Applicative g)
       => Applicative (Compose f g) where
    pure :: a -> Compose f g a
    pure x = Compose $ (pure . pure) x

    (<*>) :: Compose f g (a -> b)
          -> Compose f g a
          -> Compose f g b
    (Compose f) <*> (Compose a) = Compose $ (fmap (<*>) f) <*> a


instance (Foldable f, Foldable g) =>
    Foldable (Compose f g) where
      foldMap f (Compose fga) =
        (foldMap . foldMap) f fga

instance (Traversable f, Traversable g) =>
    Traversable (Compose f g) where
      traverse :: Applicative f1 => (a -> f1 b)
               -> Compose f g a
               -> f1 (Compose f g b)
      traverse f (Compose fga) =
        Compose <$> (traverse . traverse) f fga