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 [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