
Tillmann Rendel wrote:
Ronald Guida wrote:
Here's a toy language, described by a regular expression: 0(10)*110
I want to read characters, one at a time, and eventually decide to "Accept" or "Reject" a string.
Let me try to understand my options.
* With a simple Arrow, I can create a fixed sequence of "read" operations, and I can't act on the results (i.e. by choosing whether or not to keep reading) at run-time.
Nothing stops your Arrow-based RegExp-library from defining suitable combinators to implement choices in RegExp's without using ArrowChoice or ArrowApply. But if your Arrow-type is abstract, the users of your library can only use the combinators you provided, so you can safely assume they do only RegExp parsing, and optimize your Arrows in the runRegExp-function for the special case of RegExp-matching.
So it seems I was thinking too narrowly of arrows... If I think of an arrow as defining a Domain Specific Embedded Language (DSEL), then with a plain arrow, users can't embed Haskel inside the DSEL.
But if you decide to expose ArrowApply-functionality to the users of your RegExp-library, they are able to define arbitrary string matching on top of your RegExp library, so you can't do any optimizations because you never know what your users decided to do.
If I think of a monad (ArrowApply) as defining a Domain Specific Embedded Language (DSEL), then users can embed anything they want within the DSEL.
From a software engineering point of view, the idea of Arrow-and-only-Arrow is to encode the whole computation in the internal structure of the arrow, independent of the interpreting language Haskell. This internal structure could be as expressible as Haskell. In contrast, ArrowApply and Monad use regular Haskell expressions for everything Haskell can do (like if-then-else, recursion, ...) and only encode special operations into the internal structure (like access to state, nondeterminism, ...).
This distinction is reflected in the treatment of variables in arrow-based vs. monadic code. monadic code can use normal Haskell variables, arrow-based code has to keep the variables "inside" the arrow in some structure.
So if I want to explain arrows and monads as concisely as possible: Arrows and monads are abstract data types used to construct Domain Specific Embedded Languages (DSELs) within Haskel. A simple arrow provides a closed DSEL. A monad is a special type of arrow that creates an open DSEL by allowing users to embed arbitrary Haskel within it. -- Ron