This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2016-01-29
Channels
- # aatree (1)
- # admin-announcements (7)
- # announcements (3)
- # beginners (125)
- # boot (164)
- # braid-chat (8)
- # cider (26)
- # cljsrn (37)
- # clojars (3)
- # clojure (162)
- # clojure-argentina (1)
- # clojure-art (2)
- # clojure-berlin (5)
- # clojure-czech (3)
- # clojure-ireland (1)
- # clojure-miami (1)
- # clojure-norway (9)
- # clojure-russia (47)
- # clojurebridge (1)
- # clojurescript (151)
- # community-development (1)
- # conf-proposals (80)
- # core-async (15)
- # core-matrix (1)
- # cursive (66)
- # datomic (26)
- # emacs (17)
- # events (10)
- # funcool (59)
- # hoplon (43)
- # incanter (2)
- # jobs (10)
- # ldnclj (8)
- # lein-figwheel (18)
- # luminus (1)
- # off-topic (19)
- # om (144)
- # onyx (167)
- # overtone (9)
- # parinfer (12)
- # pedestal (1)
- # proton (158)
- # re-frame (139)
- # reagent (48)
- # test-check (19)
- # testing (43)
@niwinz: I have some problem understanding how to work with applicatives; the fail
case works intuitively, but the ok
case does not.
In Haskell I can do
Prelude> (Just (+)) <*> (Just 1) <*> (Just 3)
Just 4
but in Clojure the same results in an error:
(m/<*> (av/ok +) (av/ok 1) (av/ok 2))
java.lang.ClassCastException: java.lang.Long cannot be cast to clojure.lang.IFn
But with map it doesn't seem to work either:
(m/<*> (av/ok merge) (av/ok {:a 1}) (av/ok {:b 2}))
=> #<Ok nil>
I tried a lot of combinations and none seemed to what I expected. I basically want to take my (av/ok {:some {:coerced "value"}})
and my (av/fail {:other {:value [:error/something]]}})
and reduce them to a one av/ok
containing the validated map or to av/fail
containing validation errors.
user=> (require '[cats.labs.sugar :as s])
nil
user=> (s/ap + (maybe/just 1) (maybe/just 2))
#<Just 3>
(s/ap merge (av/ok {:a 1})
(av/ok {:b 2})
(av/fail (->ErrorContainer {:c [:fail]}))
(av/fail (->ErrorContainer {:c [:fail-two]})))
=> #<Fail #validators.core.ErrorContainer{:v {:c [:fail :fail-two]}}>
(s/ap merge (av/ok {:a 1})
(av/ok {:b 2}))
=> #<Ok {:a 1, :b 2}>
it is not very intuitive, I know, but clojure is no haskell and some of the haskell abstractions does not works in the same way in clojure
Yeah, I can see that, though in my case the number of validators is variable... but I suppose I just can count them.
But ap
seems to be more readable. Is that something that should not be used since it's in the labs
namespace?
Yeah, I can understand why it would not work - you can't curry if you have varags as you wouldn't know when to stop.
As far as I can see, it works: (m/fmap (fn [items] (m/fmap inc items)) [[1 2 3] [1 2 3]])
Yes, in this case you should specify the new context using with-context. This is something that I have explained the other day. The current approach for type/monad/context inference is a little bit limiting
(m/fmap (fn [elem]
(let [[k v] elem]
(ctx/with-context (mp/-get-context v)
[k (m/fmap inc v)])))
{:a [1 2 3] :b [1 2 3]})
I didn't understand from your previous explanation that it's needed when you nest abstractions of different type.
Yeah, not surprising at all. Types certainly help in such cases a lot, so you have to make do with what you can.
Do you plan to add a sort of stack for the contexts or implement it differently altogether?