I almost forgot how to write a "amb" operator, a non-determination operator, in scheme. Yes,
there is not only one way to implement "amb". As matter of a fact, as I known, there are three
ways, two of them used macro. I felt the following implementation easy to understand.
(define (now-fail)
"amb exhauted!")
(define-syntax amb
(syntax-rules ()
((_ e ...) (let ((old-fail now-fail))
(call/cc (lambda (sk)
(call/cc (lambda (fk)
(set! now-fail
(lambda ()
(set! now-fail old-fail)
(fk 'fail)))
(sk e)))
...
(now-fail)))))))
Yesterday I browsed some articles on Monads. What is monad? It seem that none can give a
comfortable answer, even professors or experts. In Haskell, a monad can adapted the following
operators definition.
data M a = ...
return :: a -> M a
(>>=) :: M a -> (a -> M b) -> M b
The last operator is also called as "bind" operation. It combind some functions which all
deal with a value of a Monad type. There are three laws of a monad must be obeied. They can
make sure that a monad can run correctly.
1. (return x) >>= f == f x
2. m >>= return == m
3. (m >>= f) >>= g == m >>= (/x f x >>= g)
It awaked up my memory about the laws of roborts. From the above type definition and laws,
we can know how to write a monad. There are a number of tutorial of monads. I am not going to
study it deeply. I just simulated a simple monad in scheme.
By the way, list is also a monad in scheme or Haskell. The "return" operator will make a list,
like [a]. The (>>=) is same "concatMap f [a]".
The monad seems a kind of combining programming. It separated the data and a sequence of algorithm.
A advantage of it is that we can add or append many computations as we wish. Another advantage is
also obvious that each algrithm can modify respectively.
There is a common application of a monad, I/O APIs. No matter what a port, a file pointer, a file
description, or a stream, they all can be called as monads. If you are familiar with the I/O package
of Java, you can feel easy to understand though it has not explicit (>>=) operator.
If you are not foolish, I believe that you have found the relation between (>>=) and "decorative pattern".
In my opinion, because some OOP languages have not the featurings of lambda express, of passing a lambda
express as argument, such as Java, they have to adapted other ways, such as "decorative pattern", to
implement the (>>=) operator.
Note that every function to take a value of monad must return a instance of a monad. In other words,
the function must make a monad using a original or new value. It is a key point that the (>>=) can combine
these functions. The first law and second law have telled us the (>>=) operator combine actually a monad
and a computation function base on that monad. The (>>=) must can get the value of a monad and feed it into
a monad's computation function. These functions like a group of sieves to filter a kind of type data. To
wrap a value into a monad type make the "bind" operator omitted the detail in a monad.
The third advantage is also obvious. Some algorithms, especially common algorithms, can be reused. OK,
I can give my answer about what is monad in pan-system language. That is just a trick of classification.
Usually, reusefully, flexibility is why people classification, especially in computation algorithm. It also
can improve efficiency in a way, especially manual coding. But at some case, such as hardware restriction,
or efficiency is the first quesion must be considered, classification must be proper.
Everthing is good is also bad.