File: Reader.hs

package info (click to toggle)
hugs98 98.200311-4
  • links: PTS
  • area: main
  • in suites: sarge
  • size: 12,964 kB
  • ctags: 8,084
  • sloc: ansic: 67,521; haskell: 61,497; xml: 4,566; sh: 3,264; cpp: 1,936; yacc: 1,094; makefile: 915; cs: 883; sed: 10
file content (138 lines) | stat: -rw-r--r-- 4,005 bytes parent folder | download | duplicates (2)
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
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
-----------------------------------------------------------------------------
-- |
-- Module      :  Control.Monad.Reader
-- Copyright   :  (c) Andy Gill 2001,
--		  (c) Oregon Graduate Institute of Science and Technology, 2001
-- License     :  BSD-style (see the file libraries/base/LICENSE)
-- 
-- Maintainer  :  libraries@haskell.org
-- Stability   :  experimental
-- Portability :  non-portable (multi-param classes, functional dependencies)
--
-- Declaration of the Monoid class,and instances for list and functions
--
--	  Inspired by the paper
--	  /Functional Programming with Overloading and
--	      Higher-Order Polymorphism/, 
--	    Mark P Jones (<http://www.cse.ogi.edu/~mpj/>)
--		  Advanced School of Functional Programming, 1995.
-----------------------------------------------------------------------------

module Control.Monad.Reader (
	MonadReader(..),
	asks,
	Reader(..),
	mapReader,
	withReader,
	ReaderT(..),
	mapReaderT,
	withReaderT,
	module Control.Monad,
	module Control.Monad.Fix,
	module Control.Monad.Trans,
	) where

import Prelude

import Control.Monad
import Control.Monad.Fix
import Control.Monad.Trans

-- ----------------------------------------------------------------------------
-- class MonadReader
--  asks for the internal (non-mutable) state.

class (Monad m) => MonadReader r m | m -> r where
	ask   :: m r
	local :: (r -> r) -> m a -> m a

-- This allows you to provide a projection function.

asks :: (MonadReader r m) => (r -> a) -> m a
asks f = do
	r <- ask
	return (f r)

-- ----------------------------------------------------------------------------
-- The partially applied function type is a simple reader monad

instance Functor ((->) r) where
	fmap = (.)

instance Monad ((->) r) where
	return  = const
	m >>= k = \r -> k (m r) r

instance MonadFix ((->) r) where
	mfix f = \r -> let a = f a r in a

instance MonadReader r ((->) r) where
	ask       = id
	local f m = m . f

-- ---------------------------------------------------------------------------
-- Our parameterizable reader monad

newtype Reader r a = Reader { runReader :: r -> a }

instance Functor (Reader r) where
	fmap f m = Reader $ \r -> f (runReader m r)

instance Monad (Reader r) where
	return a = Reader $ \_ -> a
	m >>= k  = Reader $ \r -> runReader (k (runReader m r)) r

instance MonadFix (Reader r) where
	mfix f = Reader $ \r -> let a = runReader (f a) r in a

instance MonadReader r (Reader r) where
	ask       = Reader id
	local f m = Reader $ runReader m . f

mapReader :: (a -> b) -> Reader r a -> Reader r b
mapReader f m = Reader $ f . runReader m

-- This is a more general version of local.

withReader :: (r' -> r) -> Reader r a -> Reader r' a
withReader f m = Reader $ runReader m . f

-- ---------------------------------------------------------------------------
-- Our parameterizable reader monad, with an inner monad

newtype ReaderT r m a = ReaderT { runReaderT :: r -> m a }

instance (Monad m) => Functor (ReaderT r m) where
	fmap f m = ReaderT $ \r -> do
		a <- runReaderT m r
		return (f a)

instance (Monad m) => Monad (ReaderT r m) where
	return a = ReaderT $ \_ -> return a
	m >>= k  = ReaderT $ \r -> do
		a <- runReaderT m r
		runReaderT (k a) r
	fail msg = ReaderT $ \_ -> fail msg

instance (MonadPlus m) => MonadPlus (ReaderT r m) where
	mzero       = ReaderT $ \_ -> mzero
	m `mplus` n = ReaderT $ \r -> runReaderT m r `mplus` runReaderT n r

instance (MonadFix m) => MonadFix (ReaderT r m) where
	mfix f = ReaderT $ \r -> mfix $ \a -> runReaderT (f a) r

instance (Monad m) => MonadReader r (ReaderT r m) where
	ask       = ReaderT return
	local f m = ReaderT $ \r -> runReaderT m (f r)

instance MonadTrans (ReaderT r) where
	lift m = ReaderT $ \_ -> m

instance (MonadIO m) => MonadIO (ReaderT r m) where
	liftIO = lift . liftIO

mapReaderT :: (m a -> n b) -> ReaderT w m a -> ReaderT w n b
mapReaderT f m = ReaderT $ f . runReaderT m

withReaderT :: (r' -> r) -> ReaderT r m a -> ReaderT r' m a
withReaderT f m = ReaderT $ runReaderT m . f