funcool / cats Goto Github PK
View Code? Open in Web Editor NEWCategory Theory and Algebraic abstractions for Clojure and ClojureScript.
Home Page: http://funcool.github.io/cats/latest/
License: BSD 2-Clause "Simplified" License
Category Theory and Algebraic abstractions for Clojure and ClojureScript.
Home Page: http://funcool.github.io/cats/latest/
License: BSD 2-Clause "Simplified" License
I've been reading about Haskell's monad transformers to clarify my understanding of the base and inner monad concepts.
[...] we will use base monad to refer to the non-transformer monad on which a transformer is based and inner monad to refer to the other monad on which the transformer is applied.
As we can see, in the Haskell implementation of transformers the 'inner' monad ends up in the transformer's type in different ways (I've added MaybeT):
Base Monad | Transformer | Original Type ("wrapped" by base) |
Combined Type ("wrapped" by transformed) |
---|---|---|---|
Maybe | MaybeT | a |
m (Maybe a) |
Writer | WriterT | (a, w) |
m (a, w) |
Reader | ReaderT | r -> a |
r -> m a |
State | StateT | s -> (a, s) |
s -> m (a, s) |
Cont | ContT | (a -> r) -> r |
(a -> m r) -> m r |
In the MaybeT
and WriterT
the resulting transformer instances end up having the 'inner' monad as the outermost wrapper. In the ReaderT
and StateT
case, the result of the functions ends up being an instance of the 'inner' monad.
I guess 'inner' is not the best name to describe a monad that a transformer wraps; the resulting type is what makes more sense for the 'base' monad, which doesn't have the 'inner' monad as the innermost wrapper.
It'd be great if we can implement some protocols conditionally when constructing a monad transformer. For example, in the state monad transformer we'd want to make the transformer instance of MonadZero
or MonadPlus
iif the inner monad is an instance of those.
Same goes for MonadWriter
, MonadReader
and MonadState
. In a transformer, if the inner monad is an instance of those the outer monad can be made one too, and the functions from those protocols can be used in the resulting transformer.
Currently cats supports on its cats.labs
namespace already supports manifold deferreds and core.async channels. Would be awesome to have also support for manifold streams under cats.labs.manifold
namespace.
The current implementation seems a little bit broken. Maybe I'm wrong but I thing it should be revisited.
https://github.com/funcool/cats/blob/master/src/cats/core.cljc#L163
Because, pure
function is used in many times that does not implements fapply
.
Map's implementation of Functor does not do what I'd expect:
p/Functor
(-fmap [_ f v]
(into {} (map f v)))
It passes the map entries to f. Not just the values. The clojure.algo.generic implementation, and the Haskell implementation in Data.Map would look something like this:
p/Functor
(-fmap [_ f v]
(into {} (map (fn [[key val]] [key (f val)]) v)))
I.e. the keys remain unchanged and f is applied to the values only. This is an example of how I would expect it to work:
=> (fmap inc {:a 1 :b 2})
{:a 2 :b 3}
Why is it not implemented way?
Hi...I'm not sure but I think than fmap or fapply must accept vararg ...
in haskell you can do
ghci> pure (+) <*> Just 3 <*> Just 3
Just 6
in fluokitten you can do
(fmap * (just 5) (just 3))
;=> (just 15)
but I can't find how do it in cats avoiding nesting fmaps (maybe I'm missing something)
defn return-nothing []
(let [c (a/chan 1)]
(a/go (a/>! c nothing))
c))
(defn return-just [v]
(let [c (a/chan 1)]
(a/go (a/>! c (just v)))
c))
a/go(
(let
[a (return-just 3)
b (fmap return-just (fmap (partial / 2) a))]
(...)
)
I tried to use foldm
the other day but it wasn't in the deployed JAR. By making this issue, I'm requesting a new deployment as soon as is agreeable.
Can help with #75.
reader, writer, state and continuation.
Now that I'm actually reading the documentation, I wonder if this shouldn't be reworded altogether (emphasis mine):
"The main difference compared to the previous example with Clojure’s map function, is that map works with seqs and doesn’t respect the input container:
(map inc [1 2 3])
;; => (2 3 4)
But why does the fmap version "work" with vectors? Because some Clojure container types like vectors, lists, and sets also implement the functor abstraction."
But really the notion of "works" is subjective because one could argue that the map version "works" by returning a lazy sequence, whereas fmap on a vector doesn't "work" (or works too hard!) because it realizes the entire mapped sequence. One can imagine situations where you would want one over the other and vice-versa.
Perhaps instead of using the tricky word "works" the differences should merely be highlighted?
Remove forwarded calls to protocols from the core namespace (use cats.protocols/extract
instead of cats.core/extract
in monad/applicative implementations).
I would open a discussion for the Context
and ContextClass
protocol naming.
The last one (ContextClass
) is introduced for identify the types that represent the context. And Context
protocol exists for make the relation between the context type (now backed by ContextClass
) and the concrete type, example: Just
or Nothing
.
As we know, at this moment the macro used for set up the context is with-context
.
Having that in mind, that are the questions here:
ContextClass
protocol name for identify a context? Maybe it should be named Context
? seems to be more semantic.Context
class for identify the types that are related to some context? (in fact them are not context object). May be this protocol should be called Contextual
or ContextAware
or something similar?It'll also be useful for testing third party implementations of Functor et al, so we should expose it somehow.
Is [funcool/cats "0.5.0"]
the preferred dependency?
Or, can we expect a [cats "0.5.0"]
soon?
Right now alet
will batch applicative value evaluations in the order they are written. This is the best default since the operation being performed might depend on ordering.
For cases where ordering is not important (for example when performing asynchronous read operations) it'd be nice to be able to tell alet
, since it might be able to optimize further.
https://github.com/funcool/cats/blob/master/.travis/test-clj.sh is missing cats.labs.*
namespaces.
Just that! Put the code under public domain :D
TypeError: Cannot set property 'cats$protocols$Contextual$' of undefined
happens on evaluating this form:
(extend-type #?(:clj clojure.lang.IFn
:cljs cljs.core.IFn)
p/Contextual
(-get-context [_] function-context))
Possible minor error in the documentation:
The main difference between foldl and reduce is that foldl has a fixed arity so all parameters are mandatory and foldl is a generic abstraction that can work with other types apart from collections.
should be
The main difference between foldl and reduce is that reduce has a fixed arity so all parameters are mandatory and foldl is a generic abstraction that can work with other types apart from collections.
I've made great use of Swiftz's >>->>
on iOS and figure we should have it here too.
This is something I'd like to work on soon.
>=>
<=<
For avoiding stack overflow errors with large monadic chains.
cats.data#Pair
(m/mapseq #(e/right (* % 2)) [])
AssertionError Assert failed: (not-empty mvs) cats.core/sequence (core.cljc:540)
I'm pretty sure this assertion is in error – If I have a context that is mappable but empty, it should return a similar empty context.
The counterparts of fns like from-maybe
, take a value and ensure that they are wrapped in the correct type.
An example of how it'd behave for Maybe:
(require '[cats.monad.maybe :as maybe])
(maybe/to-maybe (maybe/just 42))
;; => #<Just 42>
(maybe/to-maybe 3)
;; => #<Just 3>
(maybe/to-maybe nil)
;; => #<Nothing>
(maybe/to-maybe (maybe/nothing))
;; => #<Nothing>
Forgive me if I'm misunderstanding something basic, I've only just begun reading the Cats Documentation.
Under the 5.1 Functor section, there is an example of applying fmap
to a vector that is raising an exception for me:
user=> (m/fmap inc (maybe/just 1))
#<Just@4b00df11: 2>
user=> (m/fmap inc [1 2 3])
IllegalArgumentException You are using return/pure/mzero function without context. cats.core/get-current-context (core.clj:63)
Any help appreciated.
Thanks,
Sean
Hi,
I notice that a lot of functions I'm used to having around for handling Eithers in haskell are missing. In particularly, 'either', which provides for simple branching.
I've implemented it (as 'branch' to avoid having too many similarly named functions) and a few other things here: https://github.com/jjl/ednsl/blob/master/src/ednsl/util/either.clj
It's all MIT, so help yourself to anything you think is useful.
I have a little bit of familiarity with monads from Scala, but was interested in trying them with Clojure. Have set [funcool/cats "1.2.0"] in my project.clj (although have the same problem with other versions). I tried the first two lines of the tutorial in my REPL:
(require '[cats.core :as m])
(m/mappend [1 2 3] [4 5 6])
And got the following back:
IllegalArgumentException No context is set and it can not be automatically resolved. sun.reflect.NativeConstructorAccessorImpl.newInstance0 (NativeConstructorAccessorImpl.java:-2)
At this point my worse nightmare of monadic abstractions is realised :-( I am only two lines into the tutorial and I already have an incomprehensible error message.
But seriously, not sure if I am making a mistake, there is a bug in the code, a step missing in the tutorial etc.
i would like to compose applicatives for use with alet
i gather that this is achievable generically and doesn't require applicative transformers for each applicative type... though i can't find anything in cats atm
does there need to be something in cats which reifies a context for such a composed applicative ?
Is there a reason either doesn't have a MonadZero
implementation?
Haskell's Either
seems to have one.
If there are obstacles, I can perhaps pick this up. Just wanted to confirm it can be supported and you might be willing to merge a PR.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.