Hi,

I'm new to monads in clojure, and I'm loving them, they're really awesome!

But right now I need some help. Either I'm using dist-m wrong, or it's
a bug I've found.

It can be reproduced with:
clojure commit f4c58e3500b3668a0941ca21f9aa4f444de2c652
clojure-contrib commit 25fec5b5771408c30b802b67dc14a15043446a12

Both commits are for the master branch. These are the latest versions
of clojure and clojure-contrib sources that I just pulled this
morning.

This code doesn't work:

(use 'clojure.contrib.monads)
(use 'clojure.contrib.probabilities.finite-distributions)

(def die (uniform [1 2 3 4 5 6]))

(domonad dist-m
        [a die
        b die]
        [+ a b])

The error that I get:

java.lang.ClassCastException: java.lang.Integer cannot be cast to
java.util.Map$Entry
  [Thrown class java.lang.RuntimeException]

Restarts:
 0: [ABORT] Return to SLIME's top level.
 1: [CAUSE] Throw cause of this exception

Backtrace:
  0: clojure.lang.LazySeq.sval(LazySeq.java:47)
  1: clojure.lang.LazySeq.seq(LazySeq.java:56)
  2: clojure.lang.RT.seq(RT.java:440)
  3: clojure.core$seq__4245.invoke(core.clj:105)
  4: clojure.core$reduce__4500.invoke(core.clj:657)
  5: 
clojure.contrib.probabilities.finite_distributions$fn__6616$m_bind_dist__6620.invoke(finite_distributions.clj:36)
  6: user$eval__97.invoke(NO_SOURCE_FILE:1)
  7: clojure.lang.Compiler.eval(Compiler.java:4642)
  8: clojure.core$eval__5236.invoke(core.clj:2017)
  9: swank.commands.basic$eval_region__22.invoke(basic.clj:40)
 10: swank.commands.basic$eval_region__22.invoke(basic.clj:31)
 11: swank.commands.basic$listener_eval__36.invoke(basic.clj:54)
 12: clojure.lang.Var.invoke(Var.java:359)
 13: user$eval__94.invoke(NO_SOURCE_FILE)
 14: clojure.lang.Compiler.eval(Compiler.java:4642)
 15: clojure.core$eval__5236.invoke(core.clj:2017)
 16: swank.core$eval_in_emacs_package__249.invoke(core.clj:59)
 17: swank.core$eval_for_emacs__326.invoke(core.clj:128)
 18: clojure.lang.Var.invoke(Var.java:367)
 19: clojure.lang.AFn.applyToHelper(AFn.java:179)
 20: clojure.lang.Var.applyTo(Var.java:476)
 21: clojure.core$apply__4370.invoke(core.clj:436)
 22: swank.core$eval_from_control__252.invoke(core.clj:66)
 23: swank.core$eval_loop__255.invoke(core.clj:71)
 24: swank.core$spawn_repl_thread__387$fn__418$fn__420.invoke(core.clj:183)
 25: clojure.lang.AFn.applyToHelper(AFn.java:171)
 26: clojure.lang.AFn.applyTo(AFn.java:164)
 27: clojure.core$apply__4370.invoke(core.clj:436)
 28: swank.core$spawn_repl_thread__387$fn__418.doInvoke(core.clj:180)
 29: clojure.lang.RestFn.invoke(RestFn.java:402)
 30: clojure.lang.AFn.run(AFn.java:37)
 31: java.lang.Thread.run(Thread.java:619)

If I'm using dist-m correctly, I figured the reason might be that
m-bind uses merge-with to merge a collection of vectors, whereas
merge-with works with maps..?

I tried (merge-with + [:a 1] [:b 1]) and got a similar error:

clojure.lang.Keyword cannot be cast to java.util.Map$Entry
  [Thrown class java.lang.ClassCastException]

Restarts:
 0: [ABORT] Return to SLIME's top level.

Backtrace:
  0: clojure.core$key__4739.invoke(core.clj:1036)
  1: clojure.core$merge_with__5186$merge_entry__5188.invoke(core.clj:1932)
  2: clojure.lang.ArrayChunk.reduce(ArrayChunk.java:50)
  3: clojure.core$reduce__4500.invoke(core.clj:666)
  4: clojure.core$merge_with__5186$merge2__5191.invoke(core.clj:1937)
  5: clojure.core$reduce__4500.invoke(core.clj:668)
  6: clojure.core$reduce__4500.invoke(core.clj:659)
  7: clojure.core$merge_with__5186.doInvoke(core.clj:1938)
  8: clojure.lang.RestFn.invoke(RestFn.java:443)
  9: user$eval__140.invoke(NO_SOURCE_FILE:1)
<snip>

I modified dist-m to evaluate a map instead of a vector, like this:

(defmonad dist2-m
  [m-result (fn m-result-dist [v]
              {v 1})
   m-bind   (fn m-bind-dist [mv f]
              (reduce (partial merge-with +)
                      (for [[x p] mv  [y q] (f x)]
                        {y (* q p)})))
   ])

And now this code:

(domonad dist2-m
               [a die
               b die]
               (+ a b))

yields:

{2 1/36, 3 1/18, 4 1/12, 5 1/9, 6 5/36, 7 1/6, 8 5/36, 9 1/9, 10 1/12,
11 1/18, 12 1/36}

as expected.

Perhaps there's something I'm missing here?

Thanks,

Joel Rosario.
-- 
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

Reply via email to