I don't know if this is adequately "in the wild" (since it's part of a
monad lib itself), but part of my monads library uses a continuation monad
to let two mutually recursive functions traverse and rebuild a tree
structure without blowing the stack. It would be a pain to do this kind of
thing by hand, since (unlike in the typical even/odd example where the
built-in trampoline function is simple to use) the recursive calls aren't
naturally written as tail calls. The use of a continuation monad
effectively results in the functions' being rewritten in CPS, and the
implementation does the trampolining for you:

https://github.com/bwo/monads/blob/master/src/monads/cont.clj#L62

----------------------------------------------------------------------

(declare reorg-binds)

(defn- reorg-plus [m]
  (if-instance Mplus m
    (let [l (.l m)
          r (.r m)]
      (mdo li <- (reorg-binds l)
           ri <- (reorg-binds r)
           ri <- (if-instance Mplus ri
                   (let [lr (.l ri)]
                     (if-instance Mplus lr
                       (reorg-plus ri)
                       (return ri)))
                   (return ri))
           (if-instance Mplus li
             (let [l-l (.l li)]
               (mdo ri <- (reorg-plus ri)
                    (reorg-plus (Mplus. l-l (Mplus. (.r li) ri)))))
             (return (Mplus. li ri)))))
    (return m)))

(defn- reorg-binds [m]
  (if-instance Bind m
    (let [comp (.comp m)]
      (if-instance Bind comp
        (let [i-comp (.comp comp)
              i-f (.f comp)
              f (.f m)]
          (mdo i <- (reorg-plus i-comp)
               (reorg-binds (Bind. i (fn [x] (Bind. (i-f x) f))))))
        (mdo comp <- (reorg-plus comp)
             (return (Bind. comp (.f m))))))
    (return m)))

(defn reorganize
  "Reorganize the monadic computation m so that binds nested on the
left are moved to the right, i.e. transform expressions like

(>>= (>>= (>>= m f) g) h)

into expressions like

(>>= m (fn [x] (>>= (f x) (fn [y] (>>= (g y) h))))).

A monad implementation for which these two expressions give
different results is broken.

Similarly reorganizes mplus operations nested on the left:

(mplus (mplus (mplus a b) c) d)

Becomes

(mplus a (mplus b (mplus c d))).

And, similarly, an mplus operation which is not associative is
considered to be in error.

Both transformations are interleaved:

(mplus (mplus (>>= (>>= (mplus (mplus a b) c) f) g) d) e)

becomes

(mplus (>>= (mplus a (mplus b c)) (fn [x] (>>= (f x) g))) (mplus d e)).

Note that *only* mplus and bind operations are investigated: the
reorganization does not recurse into the monadic-computation
arguments of e.g. listen, local, or pass."
  [m]
  ;; this reorg-plus is here in case we fall through reorg-binds right
  ;; away. We can't call reorg-plus in reorg-binds in the else branch
  ;; of the first if-instance, because it can lead to, yes, stack
  ;; overflows.
  (run-cont (reorg-plus (run-cont (reorg-binds m)))))

----------------------------------------------------------------------





On Mon, Apr 8, 2013 at 7:56 AM, Carlos Galdino <carloshsgald...@gmail.com>wrote:

> Hi,
>
> I've been reading about monads for the past couple of weeks and I think I
> got the idea, but I still don't know when to use it since I don't have
> enough experience with functional programming.
>
> So, I'd like to ask you guys if you can point me to some examples of
> Monads usage "in the wild". Because I've seen a lot of simple examples but
> not a real one, used in a library, etc.
>
> Does anyone know a good example of real world usage?
>
> Thanks in advance.
>
> --
> --
> You received this message because you are subscribed to the Google
> Groups "Clojure" group.
> To post to this group, send email to clojure@googlegroups.com
> Note that posts from new members are moderated - please be patient with
> your first post.
> To unsubscribe from this group, send email to
> clojure+unsubscr...@googlegroups.com
> For more options, visit this group at
> http://groups.google.com/group/clojure?hl=en
> ---
> You received this message because you are subscribed to the Google Groups
> "Clojure" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to clojure+unsubscr...@googlegroups.com.
> For more options, visit https://groups.google.com/groups/opt_out.
>
>
>



-- 
Ben Wolfson
"Human kind has used its intelligence to vary the flavour of drinks, which
may be sweet, aromatic, fermented or spirit-based. ... Family and social
life also offer numerous other occasions to consume drinks for pleasure."
[Larousse, "Drink" entry]

-- 
-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.


Reply via email to