summaryrefslogtreecommitdiff
path: root/Haskell-book/22/Reader.hs
diff options
context:
space:
mode:
authorEugen Wissner <belka@caraus.de>2025-12-11 10:28:11 +0100
committerEugen Wissner <belka@caraus.de>2025-12-11 10:28:11 +0100
commit98329e0a3dd4f78b5d815ac3896272ec70904901 (patch)
tree80f9c56cfe2ac20232358f236d32e84bd683be1b /Haskell-book/22/Reader.hs
parent3624c712d72d246f21d4e710cec7c11e052e0326 (diff)
downloadbook-exercises-98329e0a3dd4f78b5d815ac3896272ec70904901.tar.gz
Add remaining haskell book exercises
Diffstat (limited to 'Haskell-book/22/Reader.hs')
-rw-r--r--Haskell-book/22/Reader.hs62
1 files changed, 62 insertions, 0 deletions
diff --git a/Haskell-book/22/Reader.hs b/Haskell-book/22/Reader.hs
new file mode 100644
index 0000000..e50b623
--- /dev/null
+++ b/Haskell-book/22/Reader.hs
@@ -0,0 +1,62 @@
+{-# LANGUAGE InstanceSigs #-}
+module Reader where
+
+import Control.Applicative (liftA2)
+
+newtype Reader r a =
+ Reader { runReader :: r -> a }
+
+myLiftA2 :: Applicative f => (a -> b -> c) -> f a -> f b -> f c
+myLiftA2 f x y = f <$> x <*> y
+
+asks :: (r -> a) -> Reader r a
+asks f = Reader f
+
+instance Functor (Reader r) where
+ fmap f (Reader x) = Reader $ f . x
+
+instance Applicative (Reader r) where
+ pure :: a -> Reader r a
+ pure a = Reader $ \x -> a
+ (<*>) :: Reader r (a -> b) -> Reader r a -> Reader r b
+ (Reader rab) <*> (Reader ra) = Reader $ \r -> rab r (ra r)
+
+instance Monad (Reader r) where
+ return = pure
+ (>>=) :: Reader r a -> (a -> Reader r b) -> Reader r b
+ (Reader ra) >>= aRb = Reader $ \r -> runReader (aRb (ra r)) r
+
+newtype HumanName = HumanName String deriving (Eq, Show)
+newtype DogName = DogName String deriving (Eq, Show)
+newtype Address = Address String deriving (Eq, Show)
+
+data Person = Person { humanName :: HumanName
+ , dogName :: DogName
+ , address :: Address
+ } deriving (Eq, Show)
+
+data Dog = Dog { dogsName :: DogName
+ , dogsAddress :: Address
+ } deriving (Eq, Show)
+
+pers :: Person
+pers = Person (HumanName "Big Bird")
+ (DogName "Barkley")
+ (Address "Sesame Street")
+
+chris :: Person
+chris = Person (HumanName "Chris Allen")
+ (DogName "Papu")
+ (Address "Austin")
+
+getDog :: Person -> Dog
+getDog p = Dog (dogName p) (address p)
+
+getDogR :: Person -> Dog
+getDogR = Dog <$> dogName <*> address
+
+getDogR' :: Person -> Dog
+getDogR' = liftA2 Dog dogName address
+
+getDogRM :: Person -> Dog
+getDogRM = dogName >>= (\x -> address >>= \y -> return $ Dog x y)