cs252r : Advanced Functional Programming - Fall 2006
These pages are a record of the in-class discussions for the graduate class "Advanced Functional Programming" given at Harvard University in the Fall of 2006.October 16, 2006
- The Essence of Functional Programming. Philip Wadler.
Is Parser a monad? If so, what are the monad operations? If not, is it related to a monad and if so, how?
Recall, that the Parser type is defined as:
type Parser a b = [a] -> [(b,[a])]
Arguing using the types, we need to define operations unit and bind with types:
unit :: x -> M x bind :: M x -> (x -> M y) -> M y
Therefore, instantiating M and x with (Parser a) and b, we get that (Parser a) is a monad. The operations can be implemented as:
unit x = \s -> [(x,s)] bind m f = \s -> concatMap (\(b,s2) -> f b s2) (m s)
The class wondered why we cared about making a monad out of our parsing combinators at all. The discussion revolved around the argument that parser combinators are easier to compose, and allow you to do more. The parser monad gives you sequencing, and limits what you can do. There was a proposition that alt could not be written without making it primitive to the monad.
remark: The alt function could be written if the Parser type had been expressed as a state monad transformer.
If we write backtrack for the L monad, and Error for the E monad, consider the following type definitions:
type LE a = Backtrack (Error a) type EL a = Error (Backtrack a)
Is LE a monad? If so, what are the monad operations.
Is EL a monad? If so, what are the monad operations.
At this point, the class spent a great deal of time trying to define combined LE and EL monads by writing out new unit and bind operations for each. Very quickly, the unit operations were found to be the composition of the original E and L units. The class had more difficulty with the bind operations. The class came up with a bind operation for the LE monad.
m `bindLE` k = [ b | x <- m,
b <- case x of
Suc a -> k a
Err s -> [Err s]
]
In retrospect, the class pointed out that the inner part of bindLE is exactly bindE. Using this insight, the class defined bindEL.
m `bindEL` k = m `bindE` (choose . map k)
The core of the issue is what to do with the list of (EL a) computations to produce a single (EL a); that is, how do we define choose?
remark: The "choose" function was written by the course staff in an effort to summarize the discussion more concisely.
Informally, how would you describe a computation of type LE a?
Informally, how would you describe a computation of type EL a?
What functions, if any, exist with type: (LE a -> EL a)
What functions, if any, exist with type: (EL a -> LE a)
Of the functions above, is any of them a homomorphism?
BibTeX
@InProceedings{Philip-Wadler1992
, url = "http://homepages.inf.ed.ac.uk/wadler/topics/monads.html"
, title = "The Essence of Functional Programming"
, address = "Albequerque, New Mexico"
, year = 1992
, author = "Philip Wadler"
, pages = "1--14"
, booktitle = "Nineteenth Annual ACM SIGPLAN Symposium on Principles of Programming Languages"
}