Yes, your monad was the first monad that I was talking about—in fact,
I followed your tutorial when I was learning about monads, and I used
your examples to create an entire parsing library. I believe that it's
essentially equivalent to (state-t maybe-m), except that you use list
pairs instead of vector pairs. (Great job on the tutorial, by the way.
It taught me everything I knew about monads.)

In that old monad above, a monadic value's success is represented by a
vector (or a list in your example) failure result is entirely
represented by a nil. I need to change this so that failure results
are represented by regular vectors with a special first value while
preserving state—i.e., [::failure state-at-time-of-failure].

So in my new monad, for instance, the "any-char" function monadic-
value from your tutorial would instead by represented by:
(defn any-char [strn]
      (if (= "" strn)
          [::failure strn]
          (list (first strn) (. strn (substring 1)))))

The code I posted in my original post works, except for m-zero. I
cannot figure out the proper value of m-zero so that it fulfills the
required axioms of m-zero. In the original parsing monad, it was easy
to figure out, because it's just any function that always returns nil.
But now, monadic values' failure results, like successful results, are
just vector/list pairs too.

I'll repost my code formatted for Google Group's proportional font,
with the definition of failure? included:

  (defn failure? [result]
    (= ::failure (get result 0)))

  (defmonad parser-m
    "The monad that FnParse uses."
    [m-zero (fn [state] [::failure state])
     m-result (fn m-result-parser [product]
                    (fn [state] [product state]))
     m-bind (fn m-bind-parser [rule product-fn]
                 (fn [state]
                  (let [result (rule state)]
                   (if (failure? result)
                     result
                     (let [[product new-state] result]
                       ((product-fn product) new-state))))))
     m-plus (fn m-plus-parser [& rules]
                 (fn [state]
                  (or (first (drop-while failure?
                              (map #(% state) rules)))
                       (m-zero state))))])

My tests show me that everything works instead of m-zero, which
doesn't fulfill its axioms. This makes using :when clauses in domacro
work incorrectly for reasons I can't explain. What is this monad's
proper value of m-zero?

On Nov 21, 8:28 am, jim <[email protected]> wrote:
> Samppi,
>
> Here's a parser-m monad I did.
>
> (defmonad parser-m
>           [m-result (fn [x]
>                         (fn [strn]
>                             (list x strn)))
>
>            m-bind (fn [parser func]
>                       (fn [strn]
>                           (let [result (parser strn)]
>                                (when (not= nil result)
>                                ((func (first result)) (second
> result))))))
>
>            m-zero (fn [strn]
>                       nil)
>
>            m-plus (fn [& parsers]
>                       (fn [strn]
>                           (first
>                                 (drop-while nil?
>                                             (map #(% strn)
> parsers)))))])
>
> I explain it in:
>
> http://intensivesystems.net/tutorials/monads_101.html
>
> What kind of parsing are you doing?
>
> Jim

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to [email protected]
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en

Reply via email to