Sat Apr 12 13:03:46 EDT 2008


so.. from the point of 'map' and 'join', which i think are easier to

  map:  take a function f:u->t, and turn it into Mu->Mt

  join: take MMt to Mt: undo a 'double wrap'

the key insight is that how many times f is used, and in what order is
not specified. and for join, it doesn't matter what the wrapping does,
as long as it can be flattened: wrapping can contain multiple base
type instances, in whatever structure.

maybe 'bind' isn't that hard to understand after all, it takes a monad
Mt and a function that produces a monad Mu from a value t, unwraps Mt,
applies t->Mu as many ways as necessary, and combines all the Mu into
a single Mu.

in the map/join version, the ORDER of wrapping is very important.

((map f) m) == (bind m (lambda (x) (return f x)))
(join m)    == (bind m (lambda (x) x))
(bind m f)  == (join ((map f) m))

in order to understand this better, i'm trying to implement it
(without looking at other implementations.) see monad.ss

i'd like to make 'map' and 'join' polymorphic, but that's not quite
possible because of absence of typing information. functions could be
annotated however (do contracts help here?)

(something in the back of my head: in haskell, one can dispatch on the
return type of a function. i'm not sure if that's going to be a
problem here.. EDIT: it's about the unit operation.)

Trying to implement a monad that carries around just an extra scheme
value. This is the simplest thing i can think of.

(define-struct extra-monad (value extra)

(define (extra-map t->u)
   ((extra-monad value extra)
    (make-extra-monad (t->u value) extra)))))

(define extra-join
   ((extra-monad (extra-monad value extra-inner)
    (make-extra-monad value ???))))

The problem seems to be in the join operator. Map is simple: just
pass it on. But what does the combination do? An option is to simply
pick one of the 2.


     "You can also turn programs in continuation passing style into
     monadic form. In fact, it's a significant result (due to Andrezj
     Filinski) that all imperative programs using call/cc and state
     can be translated into a monadic style, and vice versa. So
     exceptions, nondeterminism, coroutines, and so on all have a
     monadic expression."

maybe time to formulate my question: since call/cc seems to be more
'native' to scheme, why don't i use that instead of monads?

ok.. am i allowed to try again with reset/shift ??