File: StateT.lhs

package info (click to toggle)
lhs2tex 1.9-1
  • links: PTS
  • area: main
  • in suites: sarge
  • size: 1,544 kB
  • ctags: 28
  • sloc: haskell: 3,364; sh: 2,773; makefile: 349
file content (70 lines) | stat: -rw-r--r-- 1,944 bytes parent folder | download
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
%-------------------------------=  --------------------------------------------
\subsection{State transformer}
%-------------------------------=  --------------------------------------------

%if codeOnly || showModuleHeader

> module StateT			(  module StateT  )
> where
>
> import Auxiliaries

%endif

|IO| mit internem Zustand und Fehlerbehandlung.

%if style == math
%format MkXIO (m) = m
%format unXIO (m) = m
%endif

> newtype XIO exc st a		=  MkXIO (st -> IO (Either exc a, st))

%if style /= math

> unXIO (MkXIO f)		=  f

%endif

\NB The state is preserved upon failure.

> instance Functor (XIO exc st) where
>     fmap f m			=  m >>= \a -> return (f a)
>
> instance Monad (XIO exc st) where
>     return a			=  MkXIO (\st -> return (Right a, st))
>     m >>= k			=  MkXIO (\st -> do (r, st') <- unXIO m st
>					            case r of
>				                      Left e  -> return (Left e, st')
>						      Right a -> unXIO (k a) st')

\NB We cannot replace |return (Left e, st')| by |return (r, st')| since
the type is not general enough then.

> fetch				:: XIO exc st st
> fetch				=  MkXIO (\st -> return (Right st, st))
>
> store				:: st -> XIO exc st ()
> store st'			=  MkXIO (\st -> return (Right (), st'))
>
> update			:: (st -> st) -> XIO exc st ()
> update f			=  do st <- fetch; store (f st)
>
> toIO				:: XIO exc st a -> IO a
> toIO m			=  do (a, _) <- unXIO m undefined; return (fromRight a)
>
> fromIO			:: IO a -> XIO exc st a
> fromIO m			=  MkXIO (\st -> do a <- m; return (Right a, st))
>
> raise				:: exc -> XIO exc st a
> raise e			=  MkXIO (\st -> return (Left e, st))
>
> try				:: XIO exc st a -> XIO exc' st (Either exc a)
> try m				=  MkXIO (\st -> do (r, st') <- unXIO m st; return (Right r, st'))
>
>
> handle			:: XIO exc st a -> (exc -> XIO exc' st a) -> XIO exc' st a
> handle m h			=  try m >>= either h return
>
> fromEither			:: Either exc a -> XIO exc st a
> fromEither			=  either raise return