Add remaining haskell book exercises
This commit is contained in:
3
Haskell-book/26/MaybeT/.gitignore
vendored
Normal file
3
Haskell-book/26/MaybeT/.gitignore
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
.stack-work/
|
||||
MaybeT.cabal
|
||||
*~
|
||||
2
Haskell-book/26/MaybeT/Setup.hs
Normal file
2
Haskell-book/26/MaybeT/Setup.hs
Normal file
@@ -0,0 +1,2 @@
|
||||
import Distribution.Simple
|
||||
main = defaultMain
|
||||
23
Haskell-book/26/MaybeT/package.yaml
Normal file
23
Haskell-book/26/MaybeT/package.yaml
Normal file
@@ -0,0 +1,23 @@
|
||||
name: MaybeT
|
||||
version: 0.1.0.0
|
||||
license: BSD3
|
||||
author: "Eugen Wissner"
|
||||
maintainer: "belka@caraus.de"
|
||||
copyright: "2018 Eugen Wissner"
|
||||
|
||||
dependencies:
|
||||
- base >= 4.7 && < 5
|
||||
|
||||
library:
|
||||
source-dirs: src
|
||||
|
||||
tests:
|
||||
MaybeT-test:
|
||||
main: Spec.hs
|
||||
source-dirs: test
|
||||
ghc-options:
|
||||
- -threaded
|
||||
- -rtsopts
|
||||
- -with-rtsopts=-N
|
||||
dependencies:
|
||||
- MaybeT
|
||||
56
Haskell-book/26/MaybeT/src/Either.hs
Normal file
56
Haskell-book/26/MaybeT/src/Either.hs
Normal file
@@ -0,0 +1,56 @@
|
||||
module Either where
|
||||
|
||||
import Control.Monad (liftM)
|
||||
import MonadTrans
|
||||
import MonadIO
|
||||
|
||||
newtype EitherT e m a =
|
||||
EitherT { runEitherT :: m (Either e a) }
|
||||
|
||||
-- 1
|
||||
instance Functor m => Functor (EitherT e m) where
|
||||
fmap f (EitherT x) = EitherT $ (fmap . fmap) f x
|
||||
|
||||
-- 2
|
||||
instance Applicative m => Applicative (EitherT e m) where
|
||||
pure x = EitherT $ pure $ pure x
|
||||
|
||||
(EitherT f) <*> (EitherT a) = EitherT $ (<*>) <$> f <*> a
|
||||
|
||||
-- 3
|
||||
instance Monad m => Monad (EitherT e m) where
|
||||
return = pure
|
||||
|
||||
(EitherT em) >>= f = EitherT $ do
|
||||
v <- em
|
||||
case v of
|
||||
Left y -> return $ Left y
|
||||
Right y -> runEitherT (f y)
|
||||
|
||||
|
||||
-- 4
|
||||
-- transformer version of swapEither.
|
||||
-- Hint: write swapEither first, then swapEitherT in terms of the former.
|
||||
swapEither :: Either e a -> Either a e
|
||||
swapEither (Left x) = Right x
|
||||
swapEither (Right y) = Left y
|
||||
|
||||
swapEitherT :: (Functor m)
|
||||
=> EitherT e m a
|
||||
-> EitherT a m e
|
||||
swapEitherT (EitherT x) = EitherT $ fmap swapEither x
|
||||
|
||||
-- 5. Write the transformer variant of the either catamorphism.
|
||||
eitherT :: Monad m
|
||||
=> (a -> m c)
|
||||
-> (b -> m c)
|
||||
-> EitherT a m b
|
||||
-> m c
|
||||
eitherT f g (EitherT x) = x >>= (either f g)
|
||||
|
||||
instance MonadTrans (EitherT e) where
|
||||
lift = EitherT . liftM Right
|
||||
|
||||
instance (MonadIO m)
|
||||
=> MonadIO (EitherT e m) where
|
||||
liftIO = lift . liftIO
|
||||
43
Haskell-book/26/MaybeT/src/Identity.hs
Normal file
43
Haskell-book/26/MaybeT/src/Identity.hs
Normal file
@@ -0,0 +1,43 @@
|
||||
module Identity where
|
||||
|
||||
import MonadIO
|
||||
import MonadTrans
|
||||
|
||||
newtype Identity a =
|
||||
Identity { runIdentity :: a }
|
||||
deriving (Eq, Show)
|
||||
|
||||
instance Functor Identity where
|
||||
fmap f (Identity a) = Identity (f a)
|
||||
|
||||
instance Applicative Identity where
|
||||
pure = Identity
|
||||
(Identity f) <*> (Identity a) = Identity (f a)
|
||||
|
||||
newtype IdentityT f a =
|
||||
IdentityT { runIdentityT :: f a }
|
||||
deriving (Eq, Show)
|
||||
|
||||
instance (Functor m)
|
||||
=> Functor (IdentityT m) where
|
||||
fmap f (IdentityT fa) = IdentityT (fmap f fa)
|
||||
|
||||
instance (Applicative m)
|
||||
=> Applicative (IdentityT m) where
|
||||
pure x = IdentityT (pure x)
|
||||
|
||||
(IdentityT fab) <*> (IdentityT fa) =
|
||||
IdentityT (fab <*> fa)
|
||||
|
||||
instance (Monad m)
|
||||
=> Monad (IdentityT m) where
|
||||
return = pure
|
||||
|
||||
(IdentityT ma) >>= f = IdentityT $ ma >>= runIdentityT . f
|
||||
|
||||
instance (MonadIO m)
|
||||
=> MonadIO (IdentityT m) where
|
||||
liftIO = IdentityT . liftIO
|
||||
|
||||
instance MonadTrans IdentityT where
|
||||
lift = IdentityT
|
||||
40
Haskell-book/26/MaybeT/src/Maybe.hs
Normal file
40
Haskell-book/26/MaybeT/src/Maybe.hs
Normal file
@@ -0,0 +1,40 @@
|
||||
module Maybe where
|
||||
|
||||
import Control.Monad
|
||||
import MonadIO
|
||||
import MonadTrans
|
||||
|
||||
newtype MaybeT m a =
|
||||
MaybeT { runMaybeT :: m (Maybe a) }
|
||||
|
||||
-- compare to the instance for MaybeT
|
||||
instance (Functor m)
|
||||
=> Functor (MaybeT m) where
|
||||
fmap f (MaybeT ma) =
|
||||
MaybeT $ (fmap . fmap) f ma
|
||||
|
||||
instance (Applicative m)
|
||||
=> Applicative (MaybeT m) where
|
||||
pure x = MaybeT (pure (pure x))
|
||||
|
||||
(MaybeT fab) <*> (MaybeT mma) = MaybeT $ (<*>) <$> fab <*> mma
|
||||
|
||||
instance (Monad m)
|
||||
=> Monad (MaybeT m) where
|
||||
return = pure
|
||||
|
||||
-- (>>=) :: MaybeT m a -> (a -> MaybeT m b) -> MaybeT m b
|
||||
(MaybeT ma) >>= f = MaybeT $ do
|
||||
-- ma :: m (Maybe a)
|
||||
-- v :: Maybe a
|
||||
v <- ma
|
||||
case v of
|
||||
Nothing -> return Nothing
|
||||
Just y -> runMaybeT (f y)
|
||||
|
||||
instance MonadTrans MaybeT where
|
||||
lift = MaybeT . liftM Just
|
||||
|
||||
instance (MonadIO m)
|
||||
=> MonadIO (MaybeT m) where
|
||||
liftIO = lift . liftIO
|
||||
5
Haskell-book/26/MaybeT/src/MonadIO.hs
Normal file
5
Haskell-book/26/MaybeT/src/MonadIO.hs
Normal file
@@ -0,0 +1,5 @@
|
||||
module MonadIO where
|
||||
|
||||
class (Monad m) => MonadIO m where
|
||||
-- | Lift a computation from the 'IO' monad.
|
||||
liftIO :: IO a -> m a
|
||||
7
Haskell-book/26/MaybeT/src/MonadTrans.hs
Normal file
7
Haskell-book/26/MaybeT/src/MonadTrans.hs
Normal file
@@ -0,0 +1,7 @@
|
||||
module MonadTrans where
|
||||
|
||||
class MonadTrans t where
|
||||
-- | Lift a computation from
|
||||
-- the argument monad to
|
||||
-- the constructed monad.
|
||||
lift :: (Monad m) => m a -> t m a
|
||||
35
Haskell-book/26/MaybeT/src/Reader.hs
Normal file
35
Haskell-book/26/MaybeT/src/Reader.hs
Normal file
@@ -0,0 +1,35 @@
|
||||
module Reader where
|
||||
|
||||
import MonadIO
|
||||
import MonadTrans
|
||||
|
||||
newtype ReaderT r m a =
|
||||
ReaderT { runReaderT :: r -> m a }
|
||||
|
||||
instance (Functor m)
|
||||
=> Functor (ReaderT r m) where
|
||||
fmap f (ReaderT rma) =
|
||||
ReaderT $ (fmap . fmap) f rma
|
||||
|
||||
instance (Applicative m)
|
||||
=> Applicative (ReaderT r m) where
|
||||
pure a = ReaderT (pure (pure a))
|
||||
|
||||
(ReaderT fmab) <*> (ReaderT rma) =
|
||||
ReaderT $ (<*>) <$> fmab <*> rma
|
||||
|
||||
instance (Monad m)
|
||||
=> Monad (ReaderT r m) where
|
||||
return = pure
|
||||
|
||||
(ReaderT rma) >>= f =
|
||||
ReaderT $ \r -> do
|
||||
a <- rma r
|
||||
runReaderT (f a) r
|
||||
|
||||
instance MonadTrans (ReaderT r) where
|
||||
lift = ReaderT . const
|
||||
|
||||
instance (MonadIO m)
|
||||
=> MonadIO (ReaderT r m) where
|
||||
liftIO = lift . liftIO
|
||||
41
Haskell-book/26/MaybeT/src/State.hs
Normal file
41
Haskell-book/26/MaybeT/src/State.hs
Normal file
@@ -0,0 +1,41 @@
|
||||
module State where
|
||||
|
||||
import MonadIO
|
||||
import MonadTrans
|
||||
|
||||
newtype StateT s m a =
|
||||
StateT { runStateT :: s -> m (a, s) }
|
||||
|
||||
-- 1
|
||||
instance (Functor m)
|
||||
=> Functor (StateT s m) where
|
||||
fmap f (StateT m) = StateT $ \s -> fmap first $ m s
|
||||
where first = uncurry (\t1 t2 -> ((f t1), t2))
|
||||
|
||||
-- 2
|
||||
-- Links:
|
||||
-- http://stackoverflow.com/questions/18673525/is-it-possible-to-implement-applicative-m-applicative-statet-s-m
|
||||
-- https://github.com/NICTA/course/issues/134
|
||||
instance (Monad m)
|
||||
=> Applicative (StateT s m) where
|
||||
pure x = StateT $ (\s -> pure (x, s))
|
||||
StateT g <*> StateT h = StateT $ \s -> keepFirst <$> g s <*> h s
|
||||
where keepFirst (f, s') (x, _) = (f x, s')
|
||||
|
||||
|
||||
-- 3
|
||||
instance (Monad m)
|
||||
=> Monad (StateT s m) where
|
||||
return = pure
|
||||
|
||||
(StateT sma) >>= f =
|
||||
StateT $ \s -> do
|
||||
a <- sma s
|
||||
runStateT (f $ fst a) s
|
||||
|
||||
instance MonadTrans (StateT s) where
|
||||
lift c = StateT $ \s -> c >>= (\x -> return (x, s))
|
||||
|
||||
instance (MonadIO m)
|
||||
=> MonadIO (StateT s m) where
|
||||
liftIO = lift . liftIO
|
||||
66
Haskell-book/26/MaybeT/stack.yaml
Normal file
66
Haskell-book/26/MaybeT/stack.yaml
Normal file
@@ -0,0 +1,66 @@
|
||||
# This file was automatically generated by 'stack init'
|
||||
#
|
||||
# Some commonly used options have been documented as comments in this file.
|
||||
# For advanced use and comprehensive documentation of the format, please see:
|
||||
# https://docs.haskellstack.org/en/stable/yaml_configuration/
|
||||
|
||||
# Resolver to choose a 'specific' stackage snapshot or a compiler version.
|
||||
# A snapshot resolver dictates the compiler version and the set of packages
|
||||
# to be used for project dependencies. For example:
|
||||
#
|
||||
# resolver: lts-3.5
|
||||
# resolver: nightly-2015-09-21
|
||||
# resolver: ghc-7.10.2
|
||||
# resolver: ghcjs-0.1.0_ghc-7.10.2
|
||||
# resolver:
|
||||
# name: custom-snapshot
|
||||
# location: "./custom-snapshot.yaml"
|
||||
resolver: lts-11.6
|
||||
|
||||
# User packages to be built.
|
||||
# Various formats can be used as shown in the example below.
|
||||
#
|
||||
# packages:
|
||||
# - some-directory
|
||||
# - https://example.com/foo/bar/baz-0.0.2.tar.gz
|
||||
# - location:
|
||||
# git: https://github.com/commercialhaskell/stack.git
|
||||
# commit: e7b331f14bcffb8367cd58fbfc8b40ec7642100a
|
||||
# - location: https://github.com/commercialhaskell/stack/commit/e7b331f14bcffb8367cd58fbfc8b40ec7642100a
|
||||
# extra-dep: true
|
||||
# subdirs:
|
||||
# - auto-update
|
||||
# - wai
|
||||
#
|
||||
# A package marked 'extra-dep: true' will only be built if demanded by a
|
||||
# non-dependency (i.e. a user package), and its test suites and benchmarks
|
||||
# will not be run. This is useful for tweaking upstream packages.
|
||||
packages:
|
||||
- .
|
||||
# Dependency packages to be pulled from upstream that are not in the resolver
|
||||
# (e.g., acme-missiles-0.3)
|
||||
# extra-deps: []
|
||||
|
||||
# Override default flag values for local packages and extra-deps
|
||||
# flags: {}
|
||||
|
||||
# Extra package databases containing global packages
|
||||
# extra-package-dbs: []
|
||||
|
||||
# Control whether we use the GHC we find on the path
|
||||
# system-ghc: true
|
||||
#
|
||||
# Require a specific version of stack, using version ranges
|
||||
# require-stack-version: -any # Default
|
||||
# require-stack-version: ">=1.6"
|
||||
#
|
||||
# Override the architecture used by stack, especially useful on Windows
|
||||
# arch: i386
|
||||
# arch: x86_64
|
||||
#
|
||||
# Extra directories used by stack for building
|
||||
# extra-include-dirs: [/path/to/dir]
|
||||
# extra-lib-dirs: [/path/to/dir]
|
||||
#
|
||||
# Allow a newer minor version of GHC than the snapshot specifies
|
||||
# compiler-check: newer-minor
|
||||
2
Haskell-book/26/MaybeT/test/Spec.hs
Normal file
2
Haskell-book/26/MaybeT/test/Spec.hs
Normal file
@@ -0,0 +1,2 @@
|
||||
main :: IO ()
|
||||
main = putStrLn "Test suite not yet implemented"
|
||||
Reference in New Issue
Block a user