Functional Pearls: A Poor Man's Concurrency Monad
Journal of Functional Programming (1999)
- DOI: 10.1.1.39.8039
Available from citeseerx.ist.psu.edu
or
Abstract
Without adding any primitives to the language, we define a concurrency monad transformer in Haskell. This allows us to add a limited form of concurrency to any existing monad. The atomic actions of the new monad are lifted actions of the underlying monad. Some extra operations, such as fork , to initiate new processes, are provided. We discuss the implementation, and use some examples to illustrate the usefulness of this construction.
Available from citeseerx.ist.psu.edu
Page 1
Functional Pearls: A Poor Man's Concurrency Monad
J. Functional Programming 1 (1): 1{000, January 1993
c
1993 Cambridge University Press 1
FUNCTIONAL PEARLS
A Poor Man's Concurrency Monad
Koen Claessen
Chalmers University of Technology
email: koen@cs.chalmers.se
Abstract
Without adding any primitives to the language, we dene a concurrency monad trans-
former in Haskell. This allows us to add a limited form of concurrency to any existing
monad. The atomic actions of the new monad are lifted actions of the underlying monad.
Some extra operations, such as fork , to initiate new processes, are provided. We discuss
the implementation, and use some examples to illustrate the usefulness of this construc-
tion.
1 Introduction
The concept of a monad (Wadler, 1995) is nowadays heavily used in modern func-
tional programming languages. Monads are used to model some form of computa-
tion, such as non-determinism or a stateful calculation. Not only does this solve
many of the traditional problems in functional programming, such as I/O and mu-
table state, but it also oers a general framework that abstracts over many kinds
of computation.
It is known how to use monads to model concurrency. To do this, one usually
constructs an imperative monad, with operations that resemble the Unix fork
(Jones & Hudak, 1993). For reasons of eciency and control, Concurrent Haskell
(Peyton Jones et al., 1996) even provides primitive operations, which are dened
outside the language.
This paper presents a way to model concurrency, generalising over arbitrary mon-
ads. The idea is to have atomic actions in some monad that can be lifted into a
concurrent setting. We explore this idea within the language; we will not add any
primitives.
2 Monads
To express the properties of monads in Haskell, we will use the following type class
denition. The bind operator of the monad is denoted by (?), and the unit operator
by return .
c
1993 Cambridge University Press 1
FUNCTIONAL PEARLS
A Poor Man's Concurrency Monad
Koen Claessen
Chalmers University of Technology
email: koen@cs.chalmers.se
Abstract
Without adding any primitives to the language, we dene a concurrency monad trans-
former in Haskell. This allows us to add a limited form of concurrency to any existing
monad. The atomic actions of the new monad are lifted actions of the underlying monad.
Some extra operations, such as fork , to initiate new processes, are provided. We discuss
the implementation, and use some examples to illustrate the usefulness of this construc-
tion.
1 Introduction
The concept of a monad (Wadler, 1995) is nowadays heavily used in modern func-
tional programming languages. Monads are used to model some form of computa-
tion, such as non-determinism or a stateful calculation. Not only does this solve
many of the traditional problems in functional programming, such as I/O and mu-
table state, but it also oers a general framework that abstracts over many kinds
of computation.
It is known how to use monads to model concurrency. To do this, one usually
constructs an imperative monad, with operations that resemble the Unix fork
(Jones & Hudak, 1993). For reasons of eciency and control, Concurrent Haskell
(Peyton Jones et al., 1996) even provides primitive operations, which are dened
outside the language.
This paper presents a way to model concurrency, generalising over arbitrary mon-
ads. The idea is to have atomic actions in some monad that can be lifted into a
concurrent setting. We explore this idea within the language; we will not add any
primitives.
2 Monads
To express the properties of monads in Haskell, we will use the following type class
denition. The bind operator of the monad is denoted by (?), and the unit operator
by return .
Page 2
2 Koen Claessen
class Monad m where
(?) :: m ! ( ! m ) ! m
return :: ! m
Furthermore, throughout this paper we will use the so-called do-notation as syntac-
tic sugar for monadic expressions. The following example illustrates a traditional
monadic expression on the left, and the same, written in do-notation, on the right.
expr
1
? x: do x expr
1
expr
2
? : ; expr
2
expr
3
? y: ; y expr
3
return expr
4
; return expr
4
As an example, we present a monad with output, called the writer monad. This
monad has an extra operator called write . It takes a string as argument, which
becomes output in a side eect of the monad. The bind operator (?) of the monad
has to take care of combining the output of two computations.
A monad having this operator is an instance of the following class.
class Monad m ) Writer m where
write :: String ! m ()
A typical implementation of such a monad is a pair containing the result of the
computation, together with the output produced during that computation.
type W = (; String )
instance Monad W where
(a; s) ? k = let (b; s
0
) = k a in (b; s++s
0
)
return x = (x; \")
instance Writer W where
write s = ((); s)
Note how the bind operator concatenates the output of the two subactions.
Most monads come equipped with a run function. This function executes a com-
putation, taking the values inside one level downwards. The monad W has such a
run function, we call it output , which returns the output of a computation in W .
output :: W ! String
output (a; s) = s
class Monad m where
(?) :: m ! ( ! m ) ! m
return :: ! m
Furthermore, throughout this paper we will use the so-called do-notation as syntac-
tic sugar for monadic expressions. The following example illustrates a traditional
monadic expression on the left, and the same, written in do-notation, on the right.
expr
1
? x: do x expr
1
expr
2
? : ; expr
2
expr
3
? y: ; y expr
3
return expr
4
; return expr
4
As an example, we present a monad with output, called the writer monad. This
monad has an extra operator called write . It takes a string as argument, which
becomes output in a side eect of the monad. The bind operator (?) of the monad
has to take care of combining the output of two computations.
A monad having this operator is an instance of the following class.
class Monad m ) Writer m where
write :: String ! m ()
A typical implementation of such a monad is a pair containing the result of the
computation, together with the output produced during that computation.
type W = (; String )
instance Monad W where
(a; s) ? k = let (b; s
0
) = k a in (b; s++s
0
)
return x = (x; \")
instance Writer W where
write s = ((); s)
Note how the bind operator concatenates the output of the two subactions.
Most monads come equipped with a run function. This function executes a com-
putation, taking the values inside one level downwards. The monad W has such a
run function, we call it output , which returns the output of a computation in W .
output :: W ! String
output (a; s) = s
Sign up today - FREE
Mendeley saves you time finding and organizing research. Learn more
- All your research in one place
- Add and import papers easily
- Access it anywhere, anytime
Start using Mendeley in seconds!
Readership Statistics
9 Readers on Mendeley
by Discipline
22% Mathematics
by Academic Status
22% Student (Master)
22% Ph.D. Student
11% Student (Bachelor)
by Country
22% Russia
11% United Kingdom
11% South Korea



