funcool

A channel for discussing and asking questions about Funcool libraries https://github.com/funcool/
2017-10-02T10:14:53.000034Z

Hello ๐Ÿ™‚ I have yet to use cats, but I was wondering if I can implement some kind of monadic โ€œeitherโ€ error handling/short-circuiting on arbitrary maps? I am using clj-rethinkdb, and it returns maps like:

{:changes [{:new_val {:id 1, :name "Carly Rae"}, :old_val {:id 1}}],
 :deleted 0,
 :errors 0,
 :inserted 0,
 :replaced 1,
 :skipped 0,
 :unchanged 0}
It can also returns then in a core-async channel. So how can I โ€œtellโ€ cats which maps are errors, possibly to use in โ€œmletโ€?

mccraigmccraig 2017-10-02T10:52:09.000190Z

you can define a monad context for a new type easily enough @nha - the short-circuiting behaviour can be defined in the -mbind method. if you take a look at the vanilla maybe implementation you can see how it works: https://github.com/funcool/cats/blob/master/src/cats/monad/either.cljc#L158

mccraigmccraig 2017-10-02T10:53:26.000162Z

i.e. short-circuiting involves -mbind just returning the current m-value rather than applying the m-f

2017-10-02T11:58:43.000176Z

Thanks for the reference ๐Ÿ™‚ So I should make a function (say make-monad) that take a map and returns something reified with a -mbind implementation, is that correct?

mccraigmccraig 2017-10-02T12:03:43.000210Z

@nha probably not - the monad context needs passing around either explicitly or by with-context, and is usually a global context for a given type - a reified context would be a context for a value, so sounds wrong (unless i'm misunderstanding something)

mccraigmccraig 2017-10-02T12:05:55.000404Z

or unless you are just talking about using reify to capture some closure stuff while creating a global context for your type

mccraigmccraig 2017-10-02T12:07:16.000201Z

here's another example using deftype rather than reify https://github.com/funcool/cats/blob/master/src/cats/labs/manifold.clj#L47

mccraigmccraig 2017-10-02T12:07:35.000363Z

what is the composition behaviour that you want though @nha ?

2017-10-02T12:09:55.000268Z

You are probably right - never used cats (or any language involving monads really) ๐Ÿ˜› Well I guess the correct behaviour there would be to stop executing the queries as soon as there is an :error, and return that result. Ok the deftype example clicks a bit more for me ๐Ÿ™‚ Iโ€™ll have a look thanks !

mccraigmccraig 2017-10-02T12:12:26.000431Z

there's a core.async context available too - https://github.com/funcool/cats/blob/master/src/cats/labs/channel.cljc - although i've never used that one

mccraigmccraig 2017-10-02T12:18:48.000356Z

my best guess is that you will want something like a context which [1] has monadic-values something like PromiseChan<RethinkResponse> [2] an -mbind which in the case of non-error responses passes the :changes value to the mf, and in the case of error responses just returns the RethinkResponse (in a promise-chan)

1
2017-10-02T13:02:04.000034Z

Thank you this help me getting started ๐Ÿ™‚