Re: [ANN] Fluokitten - Category theory concepts in Clojure - Functors, Applicatives, Monads, Monoids and more
*New version, 0.4.0 released:* http://fluokitten.uncomplicate.org/ has lots of documentation and tutorials. Source at: https://github.com/uncomplicate/fluokitten New features: - Added PseudoFunctor, PseudoApplicative, and PseudoMonad, to support destructive operations in Neanderthal. - Better support for functions and curried functions. - fold, foldmap, and op much improved with variadic versions. - Varargs versions of pure, return, and unit. Changes: - fmap implementation for function changed to be in line with bind; supports multi-arity functions and offer super-comp. - Collections use reducers where appropriate. - op, fold, foldmap, support multiple arguments, have better implementations. On Monday, July 22, 2013 at 4:33:48 PM UTC+2, Phillip Lord wrote: > > > > That's a good answer! I've enjoyed reading the documentation of both > fluokitten and morph and understood it. The functionality certainly > seems useful. > > Phil > > Dragan Djuricwrites: > > > If Clojure has all of the Haskell's type features, I guess there would > be > > only one Clojure monad library, more or less a direct port of Haskell's. > As > > Clojure is different, there are different ways to approach monads from > > neither of which can be the same as Haskell's, each having its pros and > > cons, so there are many libraries. Additional motivation in my case is > that > > the other libraries (except morph, which is also a newcomer) were poorly > > documented or not documented at all, and that even simple examples from > > Haskell literature were not simple at all in those libraries, and in > many > > cases, not even supported (many of them don't even define functors and > > monoids, let alone applicative functors). > > > > What I've not yet understood is what the difference is between all of > >> these libraries? > >> > >> > > > > -- > > -- > Phillip Lord, Phone: +44 (0) 191 222 7827 > Lecturer in Bioinformatics, Email: philli...@newcastle.ac.uk > > School of Computing Science, > http://homepages.cs.ncl.ac.uk/phillip.lord > Room 914 Claremont Tower, skype: russet_apples > Newcastle University, twitter: phillord > NE1 7RU > -- 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 --- You received this message because you are subscribed to the Google Groups "Clojure" group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: [ANN] Fluokitten - Category theory concepts in Clojure - Functors, Applicatives, Monads, Monoids and more
That's a good answer! I've enjoyed reading the documentation of both fluokitten and morph and understood it. The functionality certainly seems useful. Phil Dragan Djuric draga...@gmail.com writes: If Clojure has all of the Haskell's type features, I guess there would be only one Clojure monad library, more or less a direct port of Haskell's. As Clojure is different, there are different ways to approach monads from neither of which can be the same as Haskell's, each having its pros and cons, so there are many libraries. Additional motivation in my case is that the other libraries (except morph, which is also a newcomer) were poorly documented or not documented at all, and that even simple examples from Haskell literature were not simple at all in those libraries, and in many cases, not even supported (many of them don't even define functors and monoids, let alone applicative functors). What I've not yet understood is what the difference is between all of these libraries? -- -- Phillip Lord, Phone: +44 (0) 191 222 7827 Lecturer in Bioinformatics, Email: phillip.l...@newcastle.ac.uk School of Computing Science, http://homepages.cs.ncl.ac.uk/phillip.lord Room 914 Claremont Tower, skype: russet_apples Newcastle University, twitter: phillord NE1 7RU -- -- 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 --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: [ANN] Fluokitten - Category theory concepts in Clojure - Functors, Applicatives, Monads, Monoids and more
Hi Ben and everyone who participated in the discussion. Most of the issues we have been discussed (most notably mdo and agnostic return) have been implemented in the newly released version 0.3.0. No macrology was necessary for agnostic return :) Please try the new version and post your feedback. On Wednesday, July 3, 2013 9:31:58 PM UTC+2, Ben wrote: On Wed, Jul 3, 2013 at 7:49 AM, Dragan Djuric drag...@gmail.comjavascript: wrote: Monads as a Haskell construct is what the previously mentioned laws describe. Monads in category theory are defined in a category X as a triple (T, n, m) where T is a functor and m and n certan natural transformations such that certan diagrams commute. In that sense, I am not sure that even Haskell's implementation is perfectly clean. There's a lot of nitpicking to be done, but, that's not the point, and we are digressing a bit. The point is that in Fluokitten, you are expected to work within the certain monad as you agree, and since there is no type checking on the value that a function returns, it is the responsibility of the developer to make sure that it makes sense as in Clojure generally. It is fairly easy to do by passing a parameter to f that pure can use, if f implementation needs to be agnostic to the actual monad that it will be called from. There are other approaches, so the programmer can make a choice that is the best fit for the problem at hand. Even in the example that you gave from your library, what stops the programmer to shoot himself in the foot by doing basically the same thing that we are talking about here: (defn f [g] (comp atom g g)) (require '[monads.maybe :as m]) (def mc (= (return 3) (f inc))) (run-monad m/m mc) What is the result if f is broken (in the context of the monad m/m in this case)? I didn't try it, so I may be wrong, but I doubt that the Clojure compiler complains about that one. Of course the compiler doesn't complain, how could it? I'm not asking you to have the clojure compiler complain. I'm attempting to point out that your library makes it impossible to write generic functions involving monads. That is, for fluokitten, you *have* to write f as something like (comp atom g g) or (comp vector g g) or (comp just g g) or whatever. You don't have the option of writing (comp return g g) and having that work right when the function is run in *multiple* monads. Which is a major expressivity drawback, in my mind. This is basically the same thing as comes up with Armando Blancas' morph library, which is, like yours, based on protocols. The expressivity point is the key, not the nonexistent haskell-in-clojure typechecker. That's why I asked the question I asked in my first email: whether it's possible to write this function (which I've desugared): (defn tst-reader [f] (= ask (fn [env] (= (lift (f env)) (fn [_] (= (return (println here I am)) (fn [_] (return v which can operate in an instance of the reader monad transformer parametrized by an *arbitrary* inner monad---so that you don't know in advance what the return or = should be (and you don't know in advance what the lift should be, since more than one interpretation of the reader monad is possible---all that's required here is that the monad support an ask operation). I suppose you could thread specimen special return, bind, ask, and lift functions through (and if you used fancy macrology to do that, you'd have the core.monads approach), but that's really quite cumbersome. IMO, the ability to write code like that is a large part of what makes monadic abstraction powerful and interesting. -- Ben Wolfson Human kind has used its intelligence to vary the flavour of drinks, which may be sweet, aromatic, fermented or spirit-based. ... Family and social life also offer numerous other occasions to consume drinks for pleasure. [Larousse, Drink entry] -- -- 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 --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: [ANN] Fluokitten - Category theory concepts in Clojure - Functors, Applicatives, Monads, Monoids and more
Thanks for the tip, Michael. I added a notification on every page, for the TL;DR crowd, so I hope that will catch the attention of enough people and improve the future readability of the docs. On Wednesday, July 3, 2013 2:34:33 PM UTC+2, Michael Klishin wrote: 2013/7/3 Dragan Djuric drag...@gmail.com javascript: The site source is in the gh-pages branch in the main source repository on github: https://github.com/uncomplicate/fluokitten/tree/gh-pages It's worth mentioning somewhere. ClojureWerkz projects link to doc source at the top of every guide, adding a README link is fine, too. -- MK http://github.com/michaelklishin http://twitter.com/michaelklishin -- -- 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 --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: [ANN] Fluokitten - Category theory concepts in Clojure - Functors, Applicatives, Monads, Monoids and more
On Wednesday, July 3, 2013 2:06:34 AM UTC+2, Ben wrote: On Tue, Jul 2, 2013 at 4:33 PM, Dragan Djuric drag...@gmail.comjavascript: wrote: And in this case you have to explicitly specify which monad you want to use, every time you call bind. I understand that in some case it might be a preferred way, but in my opinion for most cases that I care about I prefer it the other way. No, you don't. You don't have to specify the monad you want to use until you actually want to use it: Unless you need to use two or more different monads in that function, in which case I don't see now would you do that at all. And, you have to structure the code a bit awkwardly for clojure, and have to say specifically, I want such and such monad type, and run it with a runner. I'm not saying that that is not good option. Clojure has its features and some compromise has to be made. I just prefer the sort of compromises I made for Fluokitten to the sorts of compromises made by other libraries. ; nREPL 0.1.7 user #Namespace monads.core monads.core (defn mc [x] (= (return x) (fn [a] (= (return (inc a)) (fn [b] (return (+ x (* 2 b #'monads.core/mc monads.core (def m* (mc 5)) #'monads.core/m* monads.core (require '[monads.identity :as i] '[monads.maybe :as m]) nil monads.core (run-monad i/m m*) 17 monads.core (run-monad m/m m*) #Just 17 monads.core m* is already defined in a completely agnostic way before it's run. I thought i had already demonstrated that in my previous email when I defined mc as (= (return 3) (f inc)), prior to interpreting it in the context of any particular monad. Regarding monadic laws, which one exactly demands that you cannot change the monad (not counting the fact that haskell's implementation does it that way)? Here are the laws, in Haskell: return a = k = k a m = return= m m = (\x - k x = h) = (m = k) = h It seems to me the laws are still satisfied if you keep changing monads in each bind (if compiler is not restricting it, as is the case with Haskell but not with Clojure). I suppose that may be right: you're supposed to verify that the laws obtain for a putative monad; they don't come for free just by calling something a monad. Allowing = to have the type m a - (a - n b) - n b just means that you can't verify that yours obeys the laws. If you get to choose the type of return, even the second one is up for grabs! It does seem somewhat odd to me to advertise the package as being familiar to Haskellers and to employ category-theoretic concepts and then to be so blasé about the definition of a monad. (I wonder if you can get away with this changing of type at all if you define bind in terms of fmap and join). Here is how the laws are specified (and tested) in Fluokitten (writing from the top of my head so please excuse me if I mess up something): (def return (pure [])) ;;This def is to make it more familiar for those who already read this tread, it is not actually in fluokitten tests. (def k (comp return foo bar baz)) ;; note the agnostic return. There are ways in Clojure to change what is it bound for, but I won't go into that here, It does not seem that important to me now. The point is, fluokitten supports it... (= (return a) k) = (k a) (= [1 2 3] return) = m (= [1 2 3] (fn [x] (bind (k x) h))) = (= m k h) So, if monad stays the same, everything is nice and tidy and close enough to Clojure and Haskell. Now, what would happen if monad changes after the bind? The first law does not constrain it The second does not too, since it says what happens when you bind with (pure m) not (pure n) The third, associativity, will also be satisfied Haskell compiler would complain wildly, but there is no Haskell compiler in my REPL :) Can I prove it? NO, I didn't try. As you say, most of the time you will work in the same monad. Since Clojure is dynamic, the programmer is expected to take an extra care and test that everything works as expected. But, it seems to me that, even if the monad change, (in most cases?) it will still work... On Wednesday, July 3, 2013 1:19:10 AM UTC+2, Ben wrote: IMO you *always* want the monad to stay the same---the laws describing monadic computations don't account for swapping the things out midstream, at any rate. And it pays to be able to define monadic computations without having to explicitly pass around a token to serve as the current monad. FWIW, you *can* directly translate that function into clojure: monads.core (defn f [g] (comp return g g)) #'monads.core/f monads.core (require '[monads.state :as st]) nil monads.core (st/run-state (= get-state (f inc)) 5) #Pair [7 5] monads.core (require '[monads.list :as l]) nil monads.core (require '[monads.maybe :as m]) nil monads.core (def mc (= (return 3) (f inc)))
Re: [ANN] Fluokitten - Category theory concepts in Clojure - Functors, Applicatives, Monads, Monoids and more
The specific bind implementations always get the instance of the Monad protocol the bind was called with (since it is a part of an implementation of the Monad protocol), so you use that instance as a first argument to pure. Of course, if you call bind with a function that does not make sense in a context, you'll get a runtime exception, like in the rest of Clojure. Clojure is not strongly typed, so it puts some expectations on the programmer. I am not trying to fix Clojure. Thank you for some very thoughtful comments. If you are interested, we can try to write a bit more detailed comparisons of the approaches in both libraries. On Wednesday, July 3, 2013 2:21:29 AM UTC+2, Ben wrote: On Tue, Jul 2, 2013 at 5:06 PM, Ben Wolfson wol...@gmail.comjavascript: wrote: On Tue, Jul 2, 2013 at 4:33 PM, Dragan Djuric drag...@gmail.comjavascript: wrote: Regarding monadic laws, which one exactly demands that you cannot change the monad (not counting the fact that haskell's implementation does it that way)? Here are the laws, in Haskell: return a = k = k a m = return= m m = (\x - k x = h) = (m = k) = h It seems to me the laws are still satisfied if you keep changing monads in each bind (if compiler is not restricting it, as is the case with Haskell but not with Clojure). I suppose that may be right: you're supposed to verify that the laws obtain for a putative monad; they don't come for free just by calling something a monad. Allowing = to have the type m a - (a - n b) - n b just means that you can't verify that yours obeys the laws. If you get to choose the type of return, even the second one is up for grabs! It does seem somewhat odd to me to advertise the package as being familiar to Haskellers and to employ category-theoretic concepts and then to be so blasé about the definition of a monad. (I wonder if you can get away with this changing of type at all if you define bind in terms of fmap and join). How are you even supposed to implement bind, in fact? (Never mind reasoning about what's going on in your program if you can't be certain that the code won't switch out the monad you think you're working in, when it does matter to you that you're in a specific one.) Generally for some specific monad you need to do something specific with the return of f. For instance, your seq-bind is implemented in terms of mapcat---meaning that the f that's the second argument of mapcat had better return a seqable. This doesn't work: (mapcat (comp atom inc) '(1 2 3)). -- Ben Wolfson Human kind has used its intelligence to vary the flavour of drinks, which may be sweet, aromatic, fermented or spirit-based. ... Family and social life also offer numerous other occasions to consume drinks for pleasure. [Larousse, Drink entry] -- -- 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 --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: [ANN] Fluokitten - Category theory concepts in Clojure - Functors, Applicatives, Monads, Monoids and more
This looks fantastic. I probably won't be able to resist to type check it with core.typed at some point. And enough documentation to satisfy Michael Klishin? I'm impressed :) Thanks, Ambrose On Wed, Jul 3, 2013 at 2:07 AM, Dragan Djuric draga...@gmail.com wrote: I am pleased to announce a first public release of new (and different) monads and friends library for Clojure. Extensive *documentation* is at http://fluokitten.uncomplicate.org Fluokitten is a Clojure library that implements category theory concepts, such as functors, applicative functors, monads, monoids etc. in idiomatic Clojure. Main project goals are: - Fit well into idiomatic Clojure - Clojure programmers should be able to use and understand Fluokitten like any regular Clojure library. - Fit well into Haskell monadic types conventions - programmers should be able to reuse existing widespread monadic programming know-how and easily translate it to Clojure code. - Be reasonably easy to learn - the code from the existing books, articles and tutorials for learning monadic programming, which is usually written in Haskell should be easily translatable to Clojure with Fluokitten. - Offer good performance. Please give us your feedback, and we would also love if anyone is willing to help, regardless of previous experience, so please *get involved*. There are lots of things to be improved: - If you are a native English speaker, i would really appreciate if you can help with correcting the English on the Fluokitten site and in the documentation. - Contribute your example code (your own or the ports from Haskell tutorials) to be added to Fluokitten tests. - Contribute articles and tutorials. - Do code review of the Fluokitten code and suggest improvements. - If you find bugs, report them via Fluokitten issue tracker. - If you have any additional suggestion, contact us here: http://fluokitten.uncomplicate.org/articles/community.html -- -- 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 --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out. -- -- 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 --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: [ANN] Fluokitten - Category theory concepts in Clojure - Functors, Applicatives, Monads, Monoids and more
I probably won't be able to resist to type check it with core.typed at some point. If you contribute that, or help me baking in (some) non-invasive type checking into Fluokitten, that would be FANTASTIC! I have that in vague long-term plans, but I haven't had time to look at core.typed (I only skimmed through the homepage when it was released). And enough documentation to satisfy Michael Klishin? I'm impressed :) Thanks :) Actually, one of the main project goals is to make monads (et al) approachable for beginners, and for that, docs and tutorials are the main thing. So, this library really does not make much sense without lots of documentation. I hope to even improve it on that point. -- -- 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 --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: [ANN] Fluokitten - Category theory concepts in Clojure - Functors, Applicatives, Monads, Monoids and more
On Wed, Jul 3, 2013 at 7:50 PM, Dragan Djuric draga...@gmail.com wrote: I probably won't be able to resist to type check it with core.typed at some point. If you contribute that, or help me baking in (some) non-invasive type checking into Fluokitten, that would be FANTASTIC! I have that in vague long-term plans, but I haven't had time to look at core.typed (I only skimmed through the homepage when it was released). I'm very glad you're interested! Skimming your code, you use conj a lot (via into). I'm actually working on an accurate and extensible type for conj type right now. The code looks very pure and accommodating for type checking. And enough documentation to satisfy Michael Klishin? I'm impressed :) Thanks :) Actually, one of the main project goals is to make monads (et al) approachable for beginners, and for that, docs and tutorials are the main thing. So, this library really does not make much sense without lots of documentation. I hope to even improve it on that point. Thought: Whether type signatures help for beginners here is debatable. It probably makes some parts clearer, and some parts incomprehensible. Anyway, I'll be in touch, congratulations again :) Ambrose -- -- 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 --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: [ANN] Fluokitten - Category theory concepts in Clojure - Functors, Applicatives, Monads, Monoids and more
2013/7/3 Dragan Djuric draga...@gmail.com one of the main project goals is to make monads (et al) approachable for beginners, and for that, docs and tutorials are the main thing. So, this library really does not make much sense without lots of documentation. I hope to even improve it on that point. Dragan, That's a worthy goal. I tried to find the doc site source on github but couldn't. Is it open source? I think making it open source under a liberal license with a straightforward contribution policy is a good idea. Others will be able to help (as you know, everybody and their grandma in the FP community has an opinion on monads et al.) Thanks! -- MK http://github.com/michaelklishin http://twitter.com/michaelklishin -- -- 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 --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: [ANN] Fluokitten - Category theory concepts in Clojure - Functors, Applicatives, Monads, Monoids and more
Michael, The site source is in the gh-pages branch in the main source repository on github: https://github.com/uncomplicate/fluokitten/tree/gh-pages On Wednesday, July 3, 2013 2:19:07 PM UTC+2, Michael Klishin wrote: 2013/7/3 Dragan Djuric drag...@gmail.com javascript: one of the main project goals is to make monads (et al) approachable for beginners, and for that, docs and tutorials are the main thing. So, this library really does not make much sense without lots of documentation. I hope to even improve it on that point. Dragan, That's a worthy goal. I tried to find the doc site source on github but couldn't. Is it open source? I think making it open source under a liberal license with a straightforward contribution policy is a good idea. Others will be able to help (as you know, everybody and their grandma in the FP community has an opinion on monads et al.) Thanks! -- MK http://github.com/michaelklishin http://twitter.com/michaelklishin -- -- 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 --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: [ANN] Fluokitten - Category theory concepts in Clojure - Functors, Applicatives, Monads, Monoids and more
2013/7/3 Dragan Djuric draga...@gmail.com The site source is in the gh-pages branch in the main source repository on github: https://github.com/uncomplicate/fluokitten/tree/gh-pages It's worth mentioning somewhere. ClojureWerkz projects link to doc source at the top of every guide, adding a README link is fine, too. -- MK http://github.com/michaelklishin http://twitter.com/michaelklishin -- -- 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 --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: [ANN] Fluokitten - Category theory concepts in Clojure - Functors, Applicatives, Monads, Monoids and more
On Wed, Jul 3, 2013 at 12:32 AM, Dragan Djuric draga...@gmail.com wrote: On Wednesday, July 3, 2013 2:06:34 AM UTC+2, Ben wrote: On Tue, Jul 2, 2013 at 4:33 PM, Dragan Djuric drag...@gmail.com wrote: And in this case you have to explicitly specify which monad you want to use, every time you call bind. I understand that in some case it might be a preferred way, but in my opinion for most cases that I care about I prefer it the other way. No, you don't. You don't have to specify the monad you want to use until you actually want to use it: Unless you need to use two or more different monads in that function, in which case I don't see now would you do that at all. And, you have to structure the code a bit awkwardly for clojure, and have to say specifically, I want such and such monad type, and run it with a runner. I'm not saying that that is not good option. Clojure has its features and some compromise has to be made. I just prefer the sort of compromises I made for Fluokitten to the sorts of compromises made by other libraries. Well, my *very first* message demonstrated how to do that in a generic way. (defn tst-reader [f] (mdo env - ask v - (lift (f env)) (return (println here I am)) (return v))) You use more than one monad here in the same way you do it in Haskell: using a monad transformer, lifting from one to the other. Here you can do it without specifying *either* layer of the stack (as long as the first supports ask). You *never* have to say I want such and such monad type while you're writing the function, until you actually run it, and the same computation can be run with multiple different types (again, my first message demonstrated this, embedding arbitrary different effects including early exit and mutable state into that function without modifying it at all). As far as I can tell, with Fluokitten you *always* do. I suppose that may be right: you're supposed to verify that the laws obtain for a putative monad; they don't come for free just by calling something a monad. Allowing = to have the type m a - (a - n b) - n b just means that you can't verify that yours obeys the laws. If you get to choose the type of return, even the second one is up for grabs! It does seem somewhat odd to me to advertise the package as being familiar to Haskellers and to employ category-theoretic concepts and then to be so blasé about the definition of a monad. (I wonder if you can get away with this changing of type at all if you define bind in terms of fmap and join). Here is how the laws are specified (and tested) in Fluokitten (writing from the top of my head so please excuse me if I mess up something): (def return (pure [])) ;;This def is to make it more familiar for those who already read this tread, it is not actually in fluokitten tests. (def k (comp return foo bar baz)) ;; note the agnostic return. There are ways in Clojure to change what is it bound for, but I won't go into that here, It does not seem that important to me now. The point is, fluokitten supports it... That is not an agnostic return: it works only for vectors. You could change what it's bound for with, I suppose, with-redefs? (= (return a) k) = (k a) (= [1 2 3] return) = m (= [1 2 3] (fn [x] (bind (k x) h))) = (= m k h) So, if monad stays the same, everything is nice and tidy and close enough to Clojure and Haskell. Now, what would happen if monad changes after the bind? The first law does not constrain it The second does not too, since it says what happens when you bind with (pure m) not (pure n) The third, associativity, will also be satisfied Really? Let's find out! uncomplicate.fluokitten.core (def return (pure [])) #'uncomplicate.fluokitten.core/return uncomplicate.fluokitten.core (def k (comp return inc (partial * 2))) uncomplicate.fluokitten.core (= (= [1 2 3] k) (fn [x] (atom (inc x IllegalArgumentException Don't know how to create ISeq from: clojure.lang.Atom clojure.lang.RT.seqFrom (RT.java:505) uncomplicate.fluokitten.core (= [1 2 3] (fn [x] (= (k x) (fn [y] (atom (inc y)) IllegalArgumentException Don't know how to create ISeq from: clojure.lang.Atom clojure.lang.RT.seqFrom (RT.java:505) I guess you're right: they are the same. However, I think this, regarding the second law, is telling: The second does not too, since it says what happens when you bind with (pure m) not (pure n) *all* the laws only say what happen when you stay within the same monad, because the types the laws give to = and return *require* that. -- Ben Wolfson Human kind has used its intelligence to vary the flavour of drinks, which may be sweet, aromatic, fermented or spirit-based. ... Family and social life also offer numerous other occasions to consume drinks for pleasure. [Larousse, Drink entry] -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to
Re: [ANN] Fluokitten - Category theory concepts in Clojure - Functors, Applicatives, Monads, Monoids and more
On Wed, Jul 3, 2013 at 7:07 AM, Ben Wolfson wolf...@gmail.com wrote: However, I think this, regarding the second law, is telling: The second does not too, since it says what happens when you bind with (pure m) not (pure n) *all* the laws only say what happen when you stay within the same monad, because the types the laws give to = and return *require* that. Addendum, if you're going to say that the various monad laws don't apply because the types differ, then you are, whether you like it or not, not talking about monads; monads are what the laws describe. -- Ben Wolfson Human kind has used its intelligence to vary the flavour of drinks, which may be sweet, aromatic, fermented or spirit-based. ... Family and social life also offer numerous other occasions to consume drinks for pleasure. [Larousse, Drink entry] -- -- 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 --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: [ANN] Fluokitten - Category theory concepts in Clojure - Functors, Applicatives, Monads, Monoids and more
Monads as a Haskell construct is what the previously mentioned laws describe. Monads in category theory are defined in a category X as a triple (T, n, m) where T is a functor and m and n certan natural transformations such that certan diagrams commute. In that sense, I am not sure that even Haskell's implementation is perfectly clean. There's a lot of nitpicking to be done, but, that's not the point, and we are digressing a bit. The point is that in Fluokitten, you are expected to work within the certain monad as you agree, and since there is no type checking on the value that a function returns, it is the responsibility of the developer to make sure that it makes sense as in Clojure generally. It is fairly easy to do by passing a parameter to f that pure can use, if f implementation needs to be agnostic to the actual monad that it will be called from. There are other approaches, so the programmer can make a choice that is the best fit for the problem at hand. Even in the example that you gave from your library, what stops the programmer to shoot himself in the foot by doing basically the same thing that we are talking about here: (defn f [g] (comp atom g g)) (require '[monads.maybe :as m]) (def mc (= (return 3) (f inc))) (run-monad m/m mc) What is the result if f is broken (in the context of the monad m/m in this case)? I didn't try it, so I may be wrong, but I doubt that the Clojure compiler complains about that one. On Wednesday, July 3, 2013 4:11:31 PM UTC+2, Ben wrote: On Wed, Jul 3, 2013 at 7:07 AM, Ben Wolfson wol...@gmail.comjavascript: wrote: However, I think this, regarding the second law, is telling: The second does not too, since it says what happens when you bind with (pure m) not (pure n) *all* the laws only say what happen when you stay within the same monad, because the types the laws give to = and return *require* that. Addendum, if you're going to say that the various monad laws don't apply because the types differ, then you are, whether you like it or not, not talking about monads; monads are what the laws describe. -- Ben Wolfson Human kind has used its intelligence to vary the flavour of drinks, which may be sweet, aromatic, fermented or spirit-based. ... Family and social life also offer numerous other occasions to consume drinks for pleasure. [Larousse, Drink entry] -- -- 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 --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: [ANN] Fluokitten - Category theory concepts in Clojure - Functors, Applicatives, Monads, Monoids and more
I've never really used monads or monoids, but one thing that does confuse me is how come there are so may libraries for supporting them. I've been reading the documentation of morph (https://github.com/blancas/morph) recently, which is the first one I've understood. A quick look at fluokitten suggests that the doc is good also! What I've not yet understood is what the difference is between all of these libraries? Phil Dragan Djuric draga...@gmail.com writes: I am pleased to announce a first public release of new (and different) monads and friends library for Clojure. Extensive *documentation* is at http://fluokitten.uncomplicate.org Fluokitten is a Clojure library that implements category theory concepts, such as functors, applicative functors, monads, monoids etc. in idiomatic Clojure. Main project goals are: - Fit well into idiomatic Clojure - Clojure programmers should be able to use and understand Fluokitten like any regular Clojure library. - Fit well into Haskell monadic types conventions - programmers should be able to reuse existing widespread monadic programming know-how and easily translate it to Clojure code. - Be reasonably easy to learn - the code from the existing books, articles and tutorials for learning monadic programming, which is usually written in Haskell should be easily translatable to Clojure with Fluokitten. - Offer good performance. Please give us your feedback, and we would also love if anyone is willing to help, regardless of previous experience, so please *get involved*. There are lots of things to be improved: - If you are a native English speaker, i would really appreciate if you can help with correcting the English on the Fluokitten site and in the documentation. - Contribute your example code (your own or the ports from Haskell tutorials) to be added to Fluokitten tests. - Contribute articles and tutorials. - Do code review of the Fluokitten code and suggest improvements. - If you find bugs, report them via Fluokitten issue tracker. - If you have any additional suggestion, contact us here: http://fluokitten.uncomplicate.org/articles/community.html -- -- Phillip Lord, Phone: +44 (0) 191 222 7827 Lecturer in Bioinformatics, Email: phillip.l...@newcastle.ac.uk School of Computing Science, http://homepages.cs.ncl.ac.uk/phillip.lord Room 914 Claremont Tower, skype: russet_apples Newcastle University, twitter: phillord NE1 7RU -- -- 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 --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: [ANN] Fluokitten - Category theory concepts in Clojure - Functors, Applicatives, Monads, Monoids and more
If Clojure has all of the Haskell's type features, I guess there would be only one Clojure monad library, more or less a direct port of Haskell's. As Clojure is different, there are different ways to approach monads from neither of which can be the same as Haskell's, each having its pros and cons, so there are many libraries. Additional motivation in my case is that the other libraries (except morph, which is also a newcomer) were poorly documented or not documented at all, and that even simple examples from Haskell literature were not simple at all in those libraries, and in many cases, not even supported (many of them don't even define functors and monoids, let alone applicative functors). What I've not yet understood is what the difference is between all of these libraries? -- -- 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 --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: [ANN] Fluokitten - Category theory concepts in Clojure - Functors, Applicatives, Monads, Monoids and more
Hi, Am Mittwoch, 3. Juli 2013 16:49:43 UTC+2 schrieb Dragan Djuric: Monads as a Haskell construct is what the previously mentioned laws describe. Monads in category theory are defined in a category X as a triple (T, n, m) where T is a functor and m and n certan natural transformations such that certan diagrams commute. In that sense, I am not sure that even Haskell's implementation is perfectly clean. in category theory, monads are functors with additional constraints. Haskell's implementation is clean to the extend that Hask, i.e Haskell types and morphisms between them, form a category (there are some issues with laziness). The connection to the categorical definition is most easily seen if you define monads using join instead of = (bind). You basically need a functor, i.e. a type constructor with a proper fmap (check the laws here as well), and two natural transformations mu, eta. As it turns out, polymorphic functions are natural transformations in Haskell's category, i.e. they always obey the required laws, no need to check them. Let's call your functor type t, then mu and eta have the following types: mu :: a - t a -- Haskell's return eta :: t (t a) - t a -- Haskell's join The required laws now state that: eta (eta mm) = eta (fmap eta mm) eta (mu m) = eta (fmap mu m)= identity which just says that if you have something of type t (t (t a)) it does not matter whether you flatten it from the inside or outside first and if you have something of type t a, you can put it into another t from the outside or inside and flatten it to get back the identity. Now, conceptually changing the monad does not make much sense. Remember that a monad is a functor with additional structure, so we are always working in the same functor! The laws just express that we have a special functor which obeys additional properties, besides the functorial ones. Also generalizing the types of (=) to support different monads is forbidden by the laws. Try to define myBind :: (Monad m, Monad n) = m a - (a - n b) - n b-- like (=), but changes the monad and now look at the second law: x = return = x or written with explicit types: ((x :: m a) = (return :: a - m a)) :: m a = x :: m a ((x :: m a) `myBind` (return :: a - n a)) :: n a but this cannot equal (x :: m a), since it does not even have the same type! Best, Nils -- -- 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 --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: [ANN] Fluokitten - Category theory concepts in Clojure - Functors, Applicatives, Monads, Monoids and more
Yes, I agree completely, when we stay inside Haskell. However, Clojure is dynamic. Here are two objects that are equal despite having different types: Consider this case: (= [1] (list 1)) ;= true (isa? (type [1]) (list 1)) ;= false In fact, equality in Java (and Clojure) depends on the implementation of equals and hashCode, so, as in the previous example, it is possible that two things are equal while having different type. I know, these are special cases, but a library that wants to be idiomatic has to support even those special cases that are common in a language. So, a bind that operates on a vector might return a list - different types, different monad, but still equal! I am not sure what would be the best solution, I'm just giving a counterexample that illustrates why these things in Clojure are not that straightforward as in Haskell. On Wednesday, July 3, 2013 6:20:08 PM UTC+2, Nils Bertschinger wrote: Hi, Am Mittwoch, 3. Juli 2013 16:49:43 UTC+2 schrieb Dragan Djuric: Monads as a Haskell construct is what the previously mentioned laws describe. Monads in category theory are defined in a category X as a triple (T, n, m) where T is a functor and m and n certan natural transformations such that certan diagrams commute. In that sense, I am not sure that even Haskell's implementation is perfectly clean. in category theory, monads are functors with additional constraints. Haskell's implementation is clean to the extend that Hask, i.e Haskell types and morphisms between them, form a category (there are some issues with laziness). The connection to the categorical definition is most easily seen if you define monads using join instead of = (bind). You basically need a functor, i.e. a type constructor with a proper fmap (check the laws here as well), and two natural transformations mu, eta. As it turns out, polymorphic functions are natural transformations in Haskell's category, i.e. they always obey the required laws, no need to check them. Let's call your functor type t, then mu and eta have the following types: mu :: a - t a -- Haskell's return eta :: t (t a) - t a -- Haskell's join The required laws now state that: eta (eta mm) = eta (fmap eta mm) eta (mu m) = eta (fmap mu m)= identity which just says that if you have something of type t (t (t a)) it does not matter whether you flatten it from the inside or outside first and if you have something of type t a, you can put it into another t from the outside or inside and flatten it to get back the identity. Now, conceptually changing the monad does not make much sense. Remember that a monad is a functor with additional structure, so we are always working in the same functor! The laws just express that we have a special functor which obeys additional properties, besides the functorial ones. Also generalizing the types of (=) to support different monads is forbidden by the laws. Try to define myBind :: (Monad m, Monad n) = m a - (a - n b) - n b-- like (=), but changes the monad and now look at the second law: x = return = x or written with explicit types: ((x :: m a) = (return :: a - m a)) :: m a = x :: m a ((x :: m a) `myBind` (return :: a - n a)) :: n a but this cannot equal (x :: m a), since it does not even have the same type! Best, Nils -- -- 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 --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: [ANN] Fluokitten - Category theory concepts in Clojure - Functors, Applicatives, Monads, Monoids and more
On Wed, Jul 3, 2013 at 10:31 AM, Dragan Djuric draga...@gmail.com wrote: Yes, I agree completely, when we stay inside Haskell. However, Clojure is dynamic. Here are two objects that are equal despite having different types: If you're going to talk about category theory concepts, then that's the constraint you have to operate under. monad is constituted by the laws, the laws involve operations with a certain type, and that's just it. It's not a matter of being in Haskell or not, it's a matter of accurately implementing the concepts you claim to be implementing. I would actually maintain that a call to bind whose first argument is a vector but which returns a list (because it's implemented with mapcat, say) is not changing the monad, because you're actually operating in the list monad (what algo.monads calls the sequence monad, I think) and while the implementation might choose different ways of mapping the function depending on the type of the first argument to bind, that's an implementation detail. -- Ben Wolfson Human kind has used its intelligence to vary the flavour of drinks, which may be sweet, aromatic, fermented or spirit-based. ... Family and social life also offer numerous other occasions to consume drinks for pleasure. [Larousse, Drink entry] -- -- 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 --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: [ANN] Fluokitten - Category theory concepts in Clojure - Functors, Applicatives, Monads, Monoids and more
If you're going to talk about category theory concepts, then that's the constraint you have to operate under. monad is constituted by the laws, the laws involve operations with a certain type, and that's just it. It's not a matter of being in Haskell or not, it's a matter of accurately implementing the concepts you claim to be implementing. I do not want to be a nitpick, but category theory does not define monads (and functors and everything else) through types, but through categories. Categories themselves are not defined through types, but through - objects - arrows - source and target assignments between arrows and objects - assignment id from objects to arrows - partial composition of arrows - restricting axioms of associativity and identity So, not only that types are not necessary for talking about monads, even functions are not necessary, let alone the laws that are defined strictly through types and/or functions (which I suppose is a special case). But, as I said, neither it is terribly important for now, neither I am prepared (or willing) to go that deep into CT, which, not being a matematician, I do not have a desire to dedicate my life to, so I would stay away from this digression from now on :) I agree that Haskell's way is the most advanced and formally right impementation available today, but I do not agree with your and that's just it. I gave an example (and there are more) where in Clojure it's not just it, and regarding the list monad, I do not agree with you. The vector, list, lazy-seq etc, contexts are not the same, although they are similar, and in a lot of cases in Clojure programming it is very important to be certain whether you are using a vector, a list or a lazy seq. Treating everything as a list monad is enough in some cases, and not enough in others, which are common. -- -- 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 --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: [ANN] Fluokitten - Category theory concepts in Clojure - Functors, Applicatives, Monads, Monoids and more
On Wed, Jul 3, 2013 at 7:49 AM, Dragan Djuric draga...@gmail.com wrote: Monads as a Haskell construct is what the previously mentioned laws describe. Monads in category theory are defined in a category X as a triple (T, n, m) where T is a functor and m and n certan natural transformations such that certan diagrams commute. In that sense, I am not sure that even Haskell's implementation is perfectly clean. There's a lot of nitpicking to be done, but, that's not the point, and we are digressing a bit. The point is that in Fluokitten, you are expected to work within the certain monad as you agree, and since there is no type checking on the value that a function returns, it is the responsibility of the developer to make sure that it makes sense as in Clojure generally. It is fairly easy to do by passing a parameter to f that pure can use, if f implementation needs to be agnostic to the actual monad that it will be called from. There are other approaches, so the programmer can make a choice that is the best fit for the problem at hand. Even in the example that you gave from your library, what stops the programmer to shoot himself in the foot by doing basically the same thing that we are talking about here: (defn f [g] (comp atom g g)) (require '[monads.maybe :as m]) (def mc (= (return 3) (f inc))) (run-monad m/m mc) What is the result if f is broken (in the context of the monad m/m in this case)? I didn't try it, so I may be wrong, but I doubt that the Clojure compiler complains about that one. Of course the compiler doesn't complain, how could it? I'm not asking you to have the clojure compiler complain. I'm attempting to point out that your library makes it impossible to write generic functions involving monads. That is, for fluokitten, you *have* to write f as something like (comp atom g g) or (comp vector g g) or (comp just g g) or whatever. You don't have the option of writing (comp return g g) and having that work right when the function is run in *multiple* monads. Which is a major expressivity drawback, in my mind. This is basically the same thing as comes up with Armando Blancas' morph library, which is, like yours, based on protocols. The expressivity point is the key, not the nonexistent haskell-in-clojure typechecker. That's why I asked the question I asked in my first email: whether it's possible to write this function (which I've desugared): (defn tst-reader [f] (= ask (fn [env] (= (lift (f env)) (fn [_] (= (return (println here I am)) (fn [_] (return v which can operate in an instance of the reader monad transformer parametrized by an *arbitrary* inner monad---so that you don't know in advance what the return or = should be (and you don't know in advance what the lift should be, since more than one interpretation of the reader monad is possible---all that's required here is that the monad support an ask operation). I suppose you could thread specimen special return, bind, ask, and lift functions through (and if you used fancy macrology to do that, you'd have the core.monads approach), but that's really quite cumbersome. IMO, the ability to write code like that is a large part of what makes monadic abstraction powerful and interesting. -- Ben Wolfson Human kind has used its intelligence to vary the flavour of drinks, which may be sweet, aromatic, fermented or spirit-based. ... Family and social life also offer numerous other occasions to consume drinks for pleasure. [Larousse, Drink entry] -- -- 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 --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
[ANN] Fluokitten - Category theory concepts in Clojure - Functors, Applicatives, Monads, Monoids and more
I am pleased to announce a first public release of new (and different) monads and friends library for Clojure. Extensive *documentation* is at http://fluokitten.uncomplicate.org Fluokitten is a Clojure library that implements category theory concepts, such as functors, applicative functors, monads, monoids etc. in idiomatic Clojure. Main project goals are: - Fit well into idiomatic Clojure - Clojure programmers should be able to use and understand Fluokitten like any regular Clojure library. - Fit well into Haskell monadic types conventions - programmers should be able to reuse existing widespread monadic programming know-how and easily translate it to Clojure code. - Be reasonably easy to learn - the code from the existing books, articles and tutorials for learning monadic programming, which is usually written in Haskell should be easily translatable to Clojure with Fluokitten. - Offer good performance. Please give us your feedback, and we would also love if anyone is willing to help, regardless of previous experience, so please *get involved*. There are lots of things to be improved: - If you are a native English speaker, i would really appreciate if you can help with correcting the English on the Fluokitten site and in the documentation. - Contribute your example code (your own or the ports from Haskell tutorials) to be added to Fluokitten tests. - Contribute articles and tutorials. - Do code review of the Fluokitten code and suggest improvements. - If you find bugs, report them via Fluokitten issue tracker. - If you have any additional suggestion, contact us here: http://fluokitten.uncomplicate.org/articles/community.html -- -- 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 --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: [ANN] Fluokitten - Category theory concepts in Clojure - Functors, Applicatives, Monads, Monoids and more
2013/7/2 Dragan Djuric draga...@gmail.com I am pleased to announce a first public release of new (and different) monads and friends library for Clojure. Extensive *documentation* is at http://fluokitten.uncomplicate.org Good job, Dragan! -- MK http://github.com/michaelklishin http://twitter.com/michaelklishin -- -- 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 --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: [ANN] Fluokitten - Category theory concepts in Clojure - Functors, Applicatives, Monads, Monoids and more
I haven't played around with this but it looks as if the second argument to bind needs to know what kind of monad it's operating in, is that right? Would it be possible to write agnostic functions like this in this lib? monads.core (defn tst-reader [f] (mdo env - ask v - (lift (f env)) (return (println here I am)) (return v))) #'monads.core/tst-reader monads.core (require '[monads.reader :as r] '[monads.identity :as i] '[monads.state :as st] '[monads.error :as e]) nil monads.core (r/run-reader-t (r/t i/m) (tst-reader (comp return inc)) 5) here I am 6 monads.core (r/run-reader-t (r/t e/m) (tst-reader (fn [_] (throw-error early exit))) 5) #Either [:left early exit] monads.core (st/run-state (r/run-reader-t (r/t st/m) (tst-reader (fn [env] ( (modify #(assoc % :env env)) (return (dec env) 5) {}) here I am #Pair [4 {:env 5}] monads.core ? On Tue, Jul 2, 2013 at 11:07 AM, Dragan Djuric draga...@gmail.com wrote: I am pleased to announce a first public release of new (and different) monads and friends library for Clojure. Extensive *documentation* is at http://fluokitten.uncomplicate.org Fluokitten is a Clojure library that implements category theory concepts, such as functors, applicative functors, monads, monoids etc. in idiomatic Clojure. Main project goals are: - Fit well into idiomatic Clojure - Clojure programmers should be able to use and understand Fluokitten like any regular Clojure library. - Fit well into Haskell monadic types conventions - programmers should be able to reuse existing widespread monadic programming know-how and easily translate it to Clojure code. - Be reasonably easy to learn - the code from the existing books, articles and tutorials for learning monadic programming, which is usually written in Haskell should be easily translatable to Clojure with Fluokitten. - Offer good performance. Please give us your feedback, and we would also love if anyone is willing to help, regardless of previous experience, so please *get involved*. There are lots of things to be improved: - If you are a native English speaker, i would really appreciate if you can help with correcting the English on the Fluokitten site and in the documentation. - Contribute your example code (your own or the ports from Haskell tutorials) to be added to Fluokitten tests. - Contribute articles and tutorials. - Do code review of the Fluokitten code and suggest improvements. - If you find bugs, report them via Fluokitten issue tracker. - If you have any additional suggestion, contact us here: http://fluokitten.uncomplicate.org/articles/community.html -- -- 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 --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out. -- Ben Wolfson Human kind has used its intelligence to vary the flavour of drinks, which may be sweet, aromatic, fermented or spirit-based. ... Family and social life also offer numerous other occasions to consume drinks for pleasure. [Larousse, Drink entry] -- -- 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 --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: [ANN] Fluokitten - Category theory concepts in Clojure - Functors, Applicatives, Monads, Monoids and more
No, the second argument to bind only needs to be a function that takes a plain value and return a monadic value; you do not need to specify anything explicitly and it does not need to know what kind of monad it is operating on. Whatever that function returns will be a monad that the eventual second bind will operate on. Moreover, Fluokitten supports vararg bind, so the function is actually the last argument of bind in general case; it is the second argument only if there are two args. Please note that Fluokitten does not have a built-in mdo (a syntactic sugar for nested binds) for now. The reason is that Clojure itself has native constructs that do many stuff that Haskell's do does, so I am not yet sure why and if it would be useful, and if I add it how to make it non-awkward. Of course, I am open to suggestions. Also note that Fluokitten is not monad-centric, it has functors, applicatives, etc and I plan to add more categorical concepts, so It is different in that regard from other monadic Clojure libraries. That's why I would like to suggest reading the docs, most of the stuff is significantly different from other libs, and more similar (but simpler, due to the lack of legacy) to Haskell's categorical stuff. On Tuesday, July 2, 2013 9:15:10 PM UTC+2, Ben wrote: I haven't played around with this but it looks as if the second argument to bind needs to know what kind of monad it's operating in, is that right? Would it be possible to write agnostic functions like this in this lib? monads.core (defn tst-reader [f] (mdo env - ask v - (lift (f env)) (return (println here I am)) (return v))) #'monads.core/tst-reader monads.core (require '[monads.reader :as r] '[monads.identity :as i] '[monads.state :as st] '[monads.error :as e]) nil monads.core (r/run-reader-t (r/t i/m) (tst-reader (comp return inc)) 5) here I am 6 monads.core (r/run-reader-t (r/t e/m) (tst-reader (fn [_] (throw-error early exit))) 5) #Either [:left early exit] monads.core (st/run-state (r/run-reader-t (r/t st/m) (tst-reader (fn [env] ( (modify #(assoc % :env env)) (return (dec env) 5) {}) here I am #Pair [4 {:env 5}] monads.core ? On Tue, Jul 2, 2013 at 11:07 AM, Dragan Djuric drag...@gmail.comjavascript: wrote: I am pleased to announce a first public release of new (and different) monads and friends library for Clojure. Extensive *documentation* is at http://fluokitten.uncomplicate.org Fluokitten is a Clojure library that implements category theory concepts, such as functors, applicative functors, monads, monoids etc. in idiomatic Clojure. Main project goals are: - Fit well into idiomatic Clojure - Clojure programmers should be able to use and understand Fluokitten like any regular Clojure library. - Fit well into Haskell monadic types conventions - programmers should be able to reuse existing widespread monadic programming know-how and easily translate it to Clojure code. - Be reasonably easy to learn - the code from the existing books, articles and tutorials for learning monadic programming, which is usually written in Haskell should be easily translatable to Clojure with Fluokitten. - Offer good performance. Please give us your feedback, and we would also love if anyone is willing to help, regardless of previous experience, so please *get involved*. There are lots of things to be improved: - If you are a native English speaker, i would really appreciate if you can help with correcting the English on the Fluokitten site and in the documentation. - Contribute your example code (your own or the ports from Haskell tutorials) to be added to Fluokitten tests. - Contribute articles and tutorials. - Do code review of the Fluokitten code and suggest improvements. - If you find bugs, report them via Fluokitten issue tracker. - If you have any additional suggestion, contact us here: http://fluokitten.uncomplicate.org/articles/community.html -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clo...@googlegroups.comjavascript: Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+u...@googlegroups.com javascript: For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+u...@googlegroups.com javascript:. For more options, visit https://groups.google.com/groups/opt_out. -- Ben Wolfson Human kind has used its intelligence to vary the flavour of drinks, which may be sweet, aromatic, fermented or
Re: [ANN] Fluokitten - Category theory concepts in Clojure - Functors, Applicatives, Monads, Monoids and more
I did look at the docs and I don't really get how to return a monadic value in the right monad, the way return does automatically. All the examples I saw have something like vector or atom or what-have-you. On Tue, Jul 2, 2013 at 2:41 PM, Dragan Djuric draga...@gmail.com wrote: No, the second argument to bind only needs to be a function that takes a plain value and return a monadic value; you do not need to specify anything explicitly and it does not need to know what kind of monad it is operating on. Whatever that function returns will be a monad that the eventual second bind will operate on. Moreover, Fluokitten supports vararg bind, so the function is actually the last argument of bind in general case; it is the second argument only if there are two args. Please note that Fluokitten does not have a built-in mdo (a syntactic sugar for nested binds) for now. The reason is that Clojure itself has native constructs that do many stuff that Haskell's do does, so I am not yet sure why and if it would be useful, and if I add it how to make it non-awkward. Of course, I am open to suggestions. Also note that Fluokitten is not monad-centric, it has functors, applicatives, etc and I plan to add more categorical concepts, so It is different in that regard from other monadic Clojure libraries. That's why I would like to suggest reading the docs, most of the stuff is significantly different from other libs, and more similar (but simpler, due to the lack of legacy) to Haskell's categorical stuff. On Tuesday, July 2, 2013 9:15:10 PM UTC+2, Ben wrote: I haven't played around with this but it looks as if the second argument to bind needs to know what kind of monad it's operating in, is that right? Would it be possible to write agnostic functions like this in this lib? monads.core (defn tst-reader [f] (mdo env - ask v - (lift (f env)) (return (println here I am)) (return v))) #'monads.core/tst-reader monads.core (require '[monads.reader :as r] '[monads.identity :as i] '[monads.state :as st] '[monads.error :as e]) nil monads.core (r/run-reader-t (r/t i/m) (tst-reader (comp return inc)) 5) here I am 6 monads.core (r/run-reader-t (r/t e/m) (tst-reader (fn [_] (throw-error early exit))) 5) #Either [:left early exit] monads.core (st/run-state (r/run-reader-t (r/t st/m) (tst-reader (fn [env] ( (modify #(assoc % :env env)) (return (dec env) 5) {}) here I am #Pair [4 {:env 5}] monads.core ? On Tue, Jul 2, 2013 at 11:07 AM, Dragan Djuric drag...@gmail.com wrote: I am pleased to announce a first public release of new (and different) monads and friends library for Clojure. Extensive *documentation* is at http://fluokitten.**uncomplicate.orghttp://fluokitten.uncomplicate.org Fluokitten is a Clojure library that implements category theory concepts, such as functors, applicative functors, monads, monoids etc. in idiomatic Clojure. Main project goals are: - Fit well into idiomatic Clojure - Clojure programmers should be able to use and understand Fluokitten like any regular Clojure library. - Fit well into Haskell monadic types conventions - programmers should be able to reuse existing widespread monadic programming know-how and easily translate it to Clojure code. - Be reasonably easy to learn - the code from the existing books, articles and tutorials for learning monadic programming, which is usually written in Haskell should be easily translatable to Clojure with Fluokitten. - Offer good performance. Please give us your feedback, and we would also love if anyone is willing to help, regardless of previous experience, so please *get involved*. There are lots of things to be improved: - If you are a native English speaker, i would really appreciate if you can help with correcting the English on the Fluokitten site and in the documentation. - Contribute your example code (your own or the ports from Haskell tutorials) to be added to Fluokitten tests. - Contribute articles and tutorials. - Do code review of the Fluokitten code and suggest improvements. - If you find bugs, report them via Fluokitten issue tracker. - If you have any additional suggestion, contact us here: http://fluokitten.**uncomplicate.org/articles/**community.htmlhttp://fluokitten.uncomplicate.org/articles/community.html -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clo...@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+u...@**googlegroups.com For more options, visit this group at http://groups.google.com/**group/clojure?hl=enhttp://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to
Re: [ANN] Fluokitten - Category theory concepts in Clojure - Functors, Applicatives, Monads, Monoids and more
e.g., I'm not sure how to define the function f here: $ ghci GHCi, version 7.4.1: http://www.haskell.org/ghc/ :? for help Loading package ghc-prim ... linking ... done. Loading package integer-gmp ... linking ... done. Loading package base ... linking ... done. Prelude let f :: (Monad m) = (a - a) - a - m a ; f g = return . g . g Prelude Just 4 = f (2+) Just 8 Prelude [[1]] = f (2:) [[2,2,1]] Prelude import Control.Monad.State Prelude Control.Monad.State runState (get = f (+4)) 4 Loading package transformers-0.2.2.0 ... linking ... done. Loading package mtl-2.0.1.0 ... linking ... done. (12,4) Prelude Control.Monad.State On Tue, Jul 2, 2013 at 2:45 PM, Ben Wolfson wolf...@gmail.com wrote: I did look at the docs and I don't really get how to return a monadic value in the right monad, the way return does automatically. All the examples I saw have something like vector or atom or what-have-you. On Tue, Jul 2, 2013 at 2:41 PM, Dragan Djuric draga...@gmail.com wrote: No, the second argument to bind only needs to be a function that takes a plain value and return a monadic value; you do not need to specify anything explicitly and it does not need to know what kind of monad it is operating on. Whatever that function returns will be a monad that the eventual second bind will operate on. Moreover, Fluokitten supports vararg bind, so the function is actually the last argument of bind in general case; it is the second argument only if there are two args. Please note that Fluokitten does not have a built-in mdo (a syntactic sugar for nested binds) for now. The reason is that Clojure itself has native constructs that do many stuff that Haskell's do does, so I am not yet sure why and if it would be useful, and if I add it how to make it non-awkward. Of course, I am open to suggestions. Also note that Fluokitten is not monad-centric, it has functors, applicatives, etc and I plan to add more categorical concepts, so It is different in that regard from other monadic Clojure libraries. That's why I would like to suggest reading the docs, most of the stuff is significantly different from other libs, and more similar (but simpler, due to the lack of legacy) to Haskell's categorical stuff. On Tuesday, July 2, 2013 9:15:10 PM UTC+2, Ben wrote: I haven't played around with this but it looks as if the second argument to bind needs to know what kind of monad it's operating in, is that right? Would it be possible to write agnostic functions like this in this lib? monads.core (defn tst-reader [f] (mdo env - ask v - (lift (f env)) (return (println here I am)) (return v))) #'monads.core/tst-reader monads.core (require '[monads.reader :as r] '[monads.identity :as i] '[monads.state :as st] '[monads.error :as e]) nil monads.core (r/run-reader-t (r/t i/m) (tst-reader (comp return inc)) 5) here I am 6 monads.core (r/run-reader-t (r/t e/m) (tst-reader (fn [_] (throw-error early exit))) 5) #Either [:left early exit] monads.core (st/run-state (r/run-reader-t (r/t st/m) (tst-reader (fn [env] ( (modify #(assoc % :env env)) (return (dec env) 5) {}) here I am #Pair [4 {:env 5}] monads.core ? On Tue, Jul 2, 2013 at 11:07 AM, Dragan Djuric drag...@gmail.comwrote: I am pleased to announce a first public release of new (and different) monads and friends library for Clojure. Extensive *documentation* is at http://fluokitten.**uncomplicate.orghttp://fluokitten.uncomplicate.org Fluokitten is a Clojure library that implements category theory concepts, such as functors, applicative functors, monads, monoids etc. in idiomatic Clojure. Main project goals are: - Fit well into idiomatic Clojure - Clojure programmers should be able to use and understand Fluokitten like any regular Clojure library. - Fit well into Haskell monadic types conventions - programmers should be able to reuse existing widespread monadic programming know-how and easily translate it to Clojure code. - Be reasonably easy to learn - the code from the existing books, articles and tutorials for learning monadic programming, which is usually written in Haskell should be easily translatable to Clojure with Fluokitten. - Offer good performance. Please give us your feedback, and we would also love if anyone is willing to help, regardless of previous experience, so please *get involved*. There are lots of things to be improved: - If you are a native English speaker, i would really appreciate if you can help with correcting the English on the Fluokitten site and in the documentation. - Contribute your example code (your own or the ports from Haskell tutorials) to be added to Fluokitten tests. - Contribute articles and tutorials. - Do code review of the Fluokitten code and suggest improvements. - If you find bugs, report them via Fluokitten issue tracker. - If
Re: [ANN] Fluokitten - Category theory concepts in Clojure - Functors, Applicatives, Monads, Monoids and more
pure function, defined in applicative, is equivalent to return (In Haskell, in Fluokitten there is only pure). I think I understand what is your question now. Since Clojure does not support polymorphysm based on the returning argument you cannot translate that Haskell code exactly. For such a case (when you want to keep operating in the same monad without knowing which one it is), a you have to provide an argument for m in f (but that's how Clojure works :), and then apply it partially or curry it: (defn f [m g] (comp (pure m) g g)) (def c+ (curry +)) (bind [1 2 3] (f [] (c+ 2)) or (= [1 2 3] (f [] (c+ 2)) If [] really hurts your aesthetic views maybe a macro (bind* or mdo) would help, since instead of [], any vector, let's say [1 2 3] would do, but then, it's a special case when you actually want the monad to stay the same. Thank you for helpful comments, BTW :) On Wednesday, July 3, 2013 12:03:45 AM UTC+2, Ben wrote: e.g., I'm not sure how to define the function f here: $ ghci GHCi, version 7.4.1: http://www.haskell.org/ghc/ :? for help Loading package ghc-prim ... linking ... done. Loading package integer-gmp ... linking ... done. Loading package base ... linking ... done. Prelude let f :: (Monad m) = (a - a) - a - m a ; f g = return . g . g Prelude Just 4 = f (2+) Just 8 Prelude [[1]] = f (2:) [[2,2,1]] Prelude import Control.Monad.State Prelude Control.Monad.State runState (get = f (+4)) 4 Loading package transformers-0.2.2.0 ... linking ... done. Loading package mtl-2.0.1.0 ... linking ... done. (12,4) Prelude Control.Monad.State On Tue, Jul 2, 2013 at 2:45 PM, Ben Wolfson wol...@gmail.comjavascript: wrote: I did look at the docs and I don't really get how to return a monadic value in the right monad, the way return does automatically. All the examples I saw have something like vector or atom or what-have-you. On Tue, Jul 2, 2013 at 2:41 PM, Dragan Djuric drag...@gmail.comjavascript: wrote: No, the second argument to bind only needs to be a function that takes a plain value and return a monadic value; you do not need to specify anything explicitly and it does not need to know what kind of monad it is operating on. Whatever that function returns will be a monad that the eventual second bind will operate on. Moreover, Fluokitten supports vararg bind, so the function is actually the last argument of bind in general case; it is the second argument only if there are two args. Please note that Fluokitten does not have a built-in mdo (a syntactic sugar for nested binds) for now. The reason is that Clojure itself has native constructs that do many stuff that Haskell's do does, so I am not yet sure why and if it would be useful, and if I add it how to make it non-awkward. Of course, I am open to suggestions. Also note that Fluokitten is not monad-centric, it has functors, applicatives, etc and I plan to add more categorical concepts, so It is different in that regard from other monadic Clojure libraries. That's why I would like to suggest reading the docs, most of the stuff is significantly different from other libs, and more similar (but simpler, due to the lack of legacy) to Haskell's categorical stuff. On Tuesday, July 2, 2013 9:15:10 PM UTC+2, Ben wrote: I haven't played around with this but it looks as if the second argument to bind needs to know what kind of monad it's operating in, is that right? Would it be possible to write agnostic functions like this in this lib? monads.core (defn tst-reader [f] (mdo env - ask v - (lift (f env)) (return (println here I am)) (return v))) #'monads.core/tst-reader monads.core (require '[monads.reader :as r] '[monads.identity :as i] '[monads.state :as st] '[monads.error :as e]) nil monads.core (r/run-reader-t (r/t i/m) (tst-reader (comp return inc)) 5) here I am 6 monads.core (r/run-reader-t (r/t e/m) (tst-reader (fn [_] (throw-error early exit))) 5) #Either [:left early exit] monads.core (st/run-state (r/run-reader-t (r/t st/m) (tst-reader (fn [env] ( (modify #(assoc % :env env)) (return (dec env) 5) {}) here I am #Pair [4 {:env 5}] monads.core ? On Tue, Jul 2, 2013 at 11:07 AM, Dragan Djuric drag...@gmail.comwrote: I am pleased to announce a first public release of new (and different) monads and friends library for Clojure. Extensive *documentation* is at http://fluokitten.**uncomplicate.orghttp://fluokitten.uncomplicate.org Fluokitten is a Clojure library that implements category theory concepts, such as functors, applicative functors, monads, monoids etc. in idiomatic Clojure. Main project goals are: - Fit well into idiomatic Clojure - Clojure programmers should be able to use and understand Fluokitten like any regular Clojure library. - Fit well into Haskell monadic types conventions - programmers should be able to reuse
Re: [ANN] Fluokitten - Category theory concepts in Clojure - Functors, Applicatives, Monads, Monoids and more
I wanted to say THE pure function. Now I realize that pure function is ambiguous :) On Wednesday, July 3, 2013 1:03:26 AM UTC+2, Dragan Djuric wrote: pure function, defined in applicative, is equivalent to return (In Haskell, in Fluokitten there is only pure). I think I understand what is your question now. Since Clojure does not support polymorphysm based on the returning argument you cannot translate that Haskell code exactly. For such a case (when you want to keep operating in the same monad without knowing which one it is), a you have to provide an argument for m in f (but that's how Clojure works :), and then apply it partially or curry it: (defn f [m g] (comp (pure m) g g)) (def c+ (curry +)) (bind [1 2 3] (f [] (c+ 2)) or (= [1 2 3] (f [] (c+ 2)) If [] really hurts your aesthetic views maybe a macro (bind* or mdo) would help, since instead of [], any vector, let's say [1 2 3] would do, but then, it's a special case when you actually want the monad to stay the same. Thank you for helpful comments, BTW :) On Wednesday, July 3, 2013 12:03:45 AM UTC+2, Ben wrote: e.g., I'm not sure how to define the function f here: $ ghci GHCi, version 7.4.1: http://www.haskell.org/ghc/ :? for help Loading package ghc-prim ... linking ... done. Loading package integer-gmp ... linking ... done. Loading package base ... linking ... done. Prelude let f :: (Monad m) = (a - a) - a - m a ; f g = return . g . g Prelude Just 4 = f (2+) Just 8 Prelude [[1]] = f (2:) [[2,2,1]] Prelude import Control.Monad.State Prelude Control.Monad.State runState (get = f (+4)) 4 Loading package transformers-0.2.2.0 ... linking ... done. Loading package mtl-2.0.1.0 ... linking ... done. (12,4) Prelude Control.Monad.State On Tue, Jul 2, 2013 at 2:45 PM, Ben Wolfson wol...@gmail.com wrote: I did look at the docs and I don't really get how to return a monadic value in the right monad, the way return does automatically. All the examples I saw have something like vector or atom or what-have-you. On Tue, Jul 2, 2013 at 2:41 PM, Dragan Djuric drag...@gmail.com wrote: No, the second argument to bind only needs to be a function that takes a plain value and return a monadic value; you do not need to specify anything explicitly and it does not need to know what kind of monad it is operating on. Whatever that function returns will be a monad that the eventual second bind will operate on. Moreover, Fluokitten supports vararg bind, so the function is actually the last argument of bind in general case; it is the second argument only if there are two args. Please note that Fluokitten does not have a built-in mdo (a syntactic sugar for nested binds) for now. The reason is that Clojure itself has native constructs that do many stuff that Haskell's do does, so I am not yet sure why and if it would be useful, and if I add it how to make it non-awkward. Of course, I am open to suggestions. Also note that Fluokitten is not monad-centric, it has functors, applicatives, etc and I plan to add more categorical concepts, so It is different in that regard from other monadic Clojure libraries. That's why I would like to suggest reading the docs, most of the stuff is significantly different from other libs, and more similar (but simpler, due to the lack of legacy) to Haskell's categorical stuff. On Tuesday, July 2, 2013 9:15:10 PM UTC+2, Ben wrote: I haven't played around with this but it looks as if the second argument to bind needs to know what kind of monad it's operating in, is that right? Would it be possible to write agnostic functions like this in this lib? monads.core (defn tst-reader [f] (mdo env - ask v - (lift (f env)) (return (println here I am)) (return v))) #'monads.core/tst-reader monads.core (require '[monads.reader :as r] '[monads.identity :as i] '[monads.state :as st] '[monads.error :as e]) nil monads.core (r/run-reader-t (r/t i/m) (tst-reader (comp return inc)) 5) here I am 6 monads.core (r/run-reader-t (r/t e/m) (tst-reader (fn [_] (throw-error early exit))) 5) #Either [:left early exit] monads.core (st/run-state (r/run-reader-t (r/t st/m) (tst-reader (fn [env] ( (modify #(assoc % :env env)) (return (dec env) 5) {}) here I am #Pair [4 {:env 5}] monads.core ? On Tue, Jul 2, 2013 at 11:07 AM, Dragan Djuric drag...@gmail.comwrote: I am pleased to announce a first public release of new (and different) monads and friends library for Clojure. Extensive *documentation* is at http://fluokitten.**uncomplicate.orghttp://fluokitten.uncomplicate.org Fluokitten is a Clojure library that implements category theory concepts, such as functors, applicative functors, monads, monoids etc. in idiomatic Clojure. Main project goals are: - Fit well into idiomatic Clojure - Clojure programmers should be able to use and
Re: [ANN] Fluokitten - Category theory concepts in Clojure - Functors, Applicatives, Monads, Monoids and more
IMO you *always* want the monad to stay the same---the laws describing monadic computations don't account for swapping the things out midstream, at any rate. And it pays to be able to define monadic computations without having to explicitly pass around a token to serve as the current monad. FWIW, you *can* directly translate that function into clojure: monads.core (defn f [g] (comp return g g)) #'monads.core/f monads.core (require '[monads.state :as st]) nil monads.core (st/run-state (= get-state (f inc)) 5) #Pair [7 5] monads.core (require '[monads.list :as l]) nil monads.core (require '[monads.maybe :as m]) nil monads.core (def mc (= (return 3) (f inc))) #'monads.core/mc monads.core (run-monad m/m mc) #Just 5 monads.core (run-monad l/m mc) (5) monads.core (st/run-state mc {}) #Pair [5 {}] You just have to take a different approach to how the results are executed. (This is with this lib: https://github.com/bwo/monads) On Tue, Jul 2, 2013 at 4:03 PM, Dragan Djuric draga...@gmail.com wrote: pure function, defined in applicative, is equivalent to return (In Haskell, in Fluokitten there is only pure). I think I understand what is your question now. Since Clojure does not support polymorphysm based on the returning argument you cannot translate that Haskell code exactly. For such a case (when you want to keep operating in the same monad without knowing which one it is), a you have to provide an argument for m in f (but that's how Clojure works :), and then apply it partially or curry it: (defn f [m g] (comp (pure m) g g)) (def c+ (curry +)) (bind [1 2 3] (f [] (c+ 2)) or (= [1 2 3] (f [] (c+ 2)) If [] really hurts your aesthetic views maybe a macro (bind* or mdo) would help, since instead of [], any vector, let's say [1 2 3] would do, but then, it's a special case when you actually want the monad to stay the same. Thank you for helpful comments, BTW :) On Wednesday, July 3, 2013 12:03:45 AM UTC+2, Ben wrote: e.g., I'm not sure how to define the function f here: $ ghci GHCi, version 7.4.1: http://www.haskell.org/ghc/ :? for help Loading package ghc-prim ... linking ... done. Loading package integer-gmp ... linking ... done. Loading package base ... linking ... done. Prelude let f :: (Monad m) = (a - a) - a - m a ; f g = return . g . g Prelude Just 4 = f (2+) Just 8 Prelude [[1]] = f (2:) [[2,2,1]] Prelude import Control.Monad.State Prelude Control.Monad.State runState (get = f (+4)) 4 Loading package transformers-0.2.2.0 ... linking ... done. Loading package mtl-2.0.1.0 ... linking ... done. (12,4) Prelude Control.Monad.State On Tue, Jul 2, 2013 at 2:45 PM, Ben Wolfson wol...@gmail.com wrote: I did look at the docs and I don't really get how to return a monadic value in the right monad, the way return does automatically. All the examples I saw have something like vector or atom or what-have-you. On Tue, Jul 2, 2013 at 2:41 PM, Dragan Djuric drag...@gmail.com wrote: No, the second argument to bind only needs to be a function that takes a plain value and return a monadic value; you do not need to specify anything explicitly and it does not need to know what kind of monad it is operating on. Whatever that function returns will be a monad that the eventual second bind will operate on. Moreover, Fluokitten supports vararg bind, so the function is actually the last argument of bind in general case; it is the second argument only if there are two args. Please note that Fluokitten does not have a built-in mdo (a syntactic sugar for nested binds) for now. The reason is that Clojure itself has native constructs that do many stuff that Haskell's do does, so I am not yet sure why and if it would be useful, and if I add it how to make it non-awkward. Of course, I am open to suggestions. Also note that Fluokitten is not monad-centric, it has functors, applicatives, etc and I plan to add more categorical concepts, so It is different in that regard from other monadic Clojure libraries. That's why I would like to suggest reading the docs, most of the stuff is significantly different from other libs, and more similar (but simpler, due to the lack of legacy) to Haskell's categorical stuff. On Tuesday, July 2, 2013 9:15:10 PM UTC+2, Ben wrote: I haven't played around with this but it looks as if the second argument to bind needs to know what kind of monad it's operating in, is that right? Would it be possible to write agnostic functions like this in this lib? monads.core (defn tst-reader [f] (mdo env - ask v - (lift (f env)) (return (println here I am)) (return v))) #'monads.core/tst-reader monads.core (require '[monads.reader :as r] '[monads.identity :as i] '[monads.state :as st] '[monads.error :as e]) nil monads.core (r/run-reader-t (r/t i/m) (tst-reader (comp return inc)) 5) here I am 6 monads.core (r/run-reader-t (r/t e/m) (tst-reader (fn [_]
Re: [ANN] Fluokitten - Category theory concepts in Clojure - Functors, Applicatives, Monads, Monoids and more
And in this case you have to explicitly specify which monad you want to use, every time you call bind. I understand that in some case it might be a preferred way, but in my opinion for most cases that I care about I prefer it the other way. Regarding monadic laws, which one exactly demands that you cannot change the monad (not counting the fact that haskell's implementation does it that way)? Here are the laws, in Haskell: return a = k = k a m = return= m m = (\x - k x = h) = (m = k) = h It seems to me the laws are still satisfied if you keep changing monads in each bind (if compiler is not restricting it, as is the case with Haskell but not with Clojure). On Wednesday, July 3, 2013 1:19:10 AM UTC+2, Ben wrote: IMO you *always* want the monad to stay the same---the laws describing monadic computations don't account for swapping the things out midstream, at any rate. And it pays to be able to define monadic computations without having to explicitly pass around a token to serve as the current monad. FWIW, you *can* directly translate that function into clojure: monads.core (defn f [g] (comp return g g)) #'monads.core/f monads.core (require '[monads.state :as st]) nil monads.core (st/run-state (= get-state (f inc)) 5) #Pair [7 5] monads.core (require '[monads.list :as l]) nil monads.core (require '[monads.maybe :as m]) nil monads.core (def mc (= (return 3) (f inc))) #'monads.core/mc monads.core (run-monad m/m mc) #Just 5 monads.core (run-monad l/m mc) (5) monads.core (st/run-state mc {}) #Pair [5 {}] You just have to take a different approach to how the results are executed. (This is with this lib: https://github.com/bwo/monads) On Tue, Jul 2, 2013 at 4:03 PM, Dragan Djuric drag...@gmail.comjavascript: wrote: pure function, defined in applicative, is equivalent to return (In Haskell, in Fluokitten there is only pure). I think I understand what is your question now. Since Clojure does not support polymorphysm based on the returning argument you cannot translate that Haskell code exactly. For such a case (when you want to keep operating in the same monad without knowing which one it is), a you have to provide an argument for m in f (but that's how Clojure works :), and then apply it partially or curry it: (defn f [m g] (comp (pure m) g g)) (def c+ (curry +)) (bind [1 2 3] (f [] (c+ 2)) or (= [1 2 3] (f [] (c+ 2)) If [] really hurts your aesthetic views maybe a macro (bind* or mdo) would help, since instead of [], any vector, let's say [1 2 3] would do, but then, it's a special case when you actually want the monad to stay the same. Thank you for helpful comments, BTW :) On Wednesday, July 3, 2013 12:03:45 AM UTC+2, Ben wrote: e.g., I'm not sure how to define the function f here: $ ghci GHCi, version 7.4.1: http://www.haskell.org/ghc/ :? for help Loading package ghc-prim ... linking ... done. Loading package integer-gmp ... linking ... done. Loading package base ... linking ... done. Prelude let f :: (Monad m) = (a - a) - a - m a ; f g = return . g . g Prelude Just 4 = f (2+) Just 8 Prelude [[1]] = f (2:) [[2,2,1]] Prelude import Control.Monad.State Prelude Control.Monad.State runState (get = f (+4)) 4 Loading package transformers-0.2.2.0 ... linking ... done. Loading package mtl-2.0.1.0 ... linking ... done. (12,4) Prelude Control.Monad.State On Tue, Jul 2, 2013 at 2:45 PM, Ben Wolfson wol...@gmail.com wrote: I did look at the docs and I don't really get how to return a monadic value in the right monad, the way return does automatically. All the examples I saw have something like vector or atom or what-have-you. On Tue, Jul 2, 2013 at 2:41 PM, Dragan Djuric drag...@gmail.comwrote: No, the second argument to bind only needs to be a function that takes a plain value and return a monadic value; you do not need to specify anything explicitly and it does not need to know what kind of monad it is operating on. Whatever that function returns will be a monad that the eventual second bind will operate on. Moreover, Fluokitten supports vararg bind, so the function is actually the last argument of bind in general case; it is the second argument only if there are two args. Please note that Fluokitten does not have a built-in mdo (a syntactic sugar for nested binds) for now. The reason is that Clojure itself has native constructs that do many stuff that Haskell's do does, so I am not yet sure why and if it would be useful, and if I add it how to make it non-awkward. Of course, I am open to suggestions. Also note that Fluokitten is not monad-centric, it has functors, applicatives, etc and I plan to add more categorical concepts, so It is different in that regard from other monadic Clojure libraries. That's why I would like to suggest reading the docs, most of the stuff is significantly different from other libs, and more similar (but simpler, due to the
Re: [ANN] Fluokitten - Category theory concepts in Clojure - Functors, Applicatives, Monads, Monoids and more
On Tue, Jul 2, 2013 at 4:33 PM, Dragan Djuric draga...@gmail.com wrote: And in this case you have to explicitly specify which monad you want to use, every time you call bind. I understand that in some case it might be a preferred way, but in my opinion for most cases that I care about I prefer it the other way. No, you don't. You don't have to specify the monad you want to use until you actually want to use it: ; nREPL 0.1.7 user #Namespace monads.core monads.core (defn mc [x] (= (return x) (fn [a] (= (return (inc a)) (fn [b] (return (+ x (* 2 b #'monads.core/mc monads.core (def m* (mc 5)) #'monads.core/m* monads.core (require '[monads.identity :as i] '[monads.maybe :as m]) nil monads.core (run-monad i/m m*) 17 monads.core (run-monad m/m m*) #Just 17 monads.core m* is already defined in a completely agnostic way before it's run. I thought i had already demonstrated that in my previous email when I defined mc as (= (return 3) (f inc)), prior to interpreting it in the context of any particular monad. Regarding monadic laws, which one exactly demands that you cannot change the monad (not counting the fact that haskell's implementation does it that way)? Here are the laws, in Haskell: return a = k = k a m = return= m m = (\x - k x = h) = (m = k) = h It seems to me the laws are still satisfied if you keep changing monads in each bind (if compiler is not restricting it, as is the case with Haskell but not with Clojure). I suppose that may be right: you're supposed to verify that the laws obtain for a putative monad; they don't come for free just by calling something a monad. Allowing = to have the type m a - (a - n b) - n b just means that you can't verify that yours obeys the laws. If you get to choose the type of return, even the second one is up for grabs! It does seem somewhat odd to me to advertise the package as being familiar to Haskellers and to employ category-theoretic concepts and then to be so blasé about the definition of a monad. (I wonder if you can get away with this changing of type at all if you define bind in terms of fmap and join). On Wednesday, July 3, 2013 1:19:10 AM UTC+2, Ben wrote: IMO you *always* want the monad to stay the same---the laws describing monadic computations don't account for swapping the things out midstream, at any rate. And it pays to be able to define monadic computations without having to explicitly pass around a token to serve as the current monad. FWIW, you *can* directly translate that function into clojure: monads.core (defn f [g] (comp return g g)) #'monads.core/f monads.core (require '[monads.state :as st]) nil monads.core (st/run-state (= get-state (f inc)) 5) #Pair [7 5] monads.core (require '[monads.list :as l]) nil monads.core (require '[monads.maybe :as m]) nil monads.core (def mc (= (return 3) (f inc))) #'monads.core/mc monads.core (run-monad m/m mc) #Just 5 monads.core (run-monad l/m mc) (5) monads.core (st/run-state mc {}) #Pair [5 {}] You just have to take a different approach to how the results are executed. (This is with this lib: https://github.com/bwo/monads) On Tue, Jul 2, 2013 at 4:03 PM, Dragan Djuric drag...@gmail.com wrote: pure function, defined in applicative, is equivalent to return (In Haskell, in Fluokitten there is only pure). I think I understand what is your question now. Since Clojure does not support polymorphysm based on the returning argument you cannot translate that Haskell code exactly. For such a case (when you want to keep operating in the same monad without knowing which one it is), a you have to provide an argument for m in f (but that's how Clojure works :), and then apply it partially or curry it: (defn f [m g] (comp (pure m) g g)) (def c+ (curry +)) (bind [1 2 3] (f [] (c+ 2)) or (= [1 2 3] (f [] (c+ 2)) If [] really hurts your aesthetic views maybe a macro (bind* or mdo) would help, since instead of [], any vector, let's say [1 2 3] would do, but then, it's a special case when you actually want the monad to stay the same. Thank you for helpful comments, BTW :) On Wednesday, July 3, 2013 12:03:45 AM UTC+2, Ben wrote: e.g., I'm not sure how to define the function f here: $ ghci GHCi, version 7.4.1: http://www.haskell.org/ghc/ :? for help Loading package ghc-prim ... linking ... done. Loading package integer-gmp ... linking ... done. Loading package base ... linking ... done. Prelude let f :: (Monad m) = (a - a) - a - m a ; f g = return . g . g Prelude Just 4 = f (2+) Just 8 Prelude [[1]] = f (2:) [[2,2,1]] Prelude import Control.Monad.State Prelude Control.Monad.State runState (get = f (+4)) 4 Loading package transformers-0.2.2.0 ... linking ... done. Loading package mtl-2.0.1.0 ... linking ... done. (12,4) Prelude Control.Monad.State On Tue, Jul 2, 2013 at 2:45 PM, Ben Wolfson
Re: [ANN] Fluokitten - Category theory concepts in Clojure - Functors, Applicatives, Monads, Monoids and more
On Tue, Jul 2, 2013 at 5:06 PM, Ben Wolfson wolf...@gmail.com wrote: On Tue, Jul 2, 2013 at 4:33 PM, Dragan Djuric draga...@gmail.com wrote: Regarding monadic laws, which one exactly demands that you cannot change the monad (not counting the fact that haskell's implementation does it that way)? Here are the laws, in Haskell: return a = k = k a m = return= m m = (\x - k x = h) = (m = k) = h It seems to me the laws are still satisfied if you keep changing monads in each bind (if compiler is not restricting it, as is the case with Haskell but not with Clojure). I suppose that may be right: you're supposed to verify that the laws obtain for a putative monad; they don't come for free just by calling something a monad. Allowing = to have the type m a - (a - n b) - n b just means that you can't verify that yours obeys the laws. If you get to choose the type of return, even the second one is up for grabs! It does seem somewhat odd to me to advertise the package as being familiar to Haskellers and to employ category-theoretic concepts and then to be so blasé about the definition of a monad. (I wonder if you can get away with this changing of type at all if you define bind in terms of fmap and join). How are you even supposed to implement bind, in fact? (Never mind reasoning about what's going on in your program if you can't be certain that the code won't switch out the monad you think you're working in, when it does matter to you that you're in a specific one.) Generally for some specific monad you need to do something specific with the return of f. For instance, your seq-bind is implemented in terms of mapcat---meaning that the f that's the second argument of mapcat had better return a seqable. This doesn't work: (mapcat (comp atom inc) '(1 2 3)). -- Ben Wolfson Human kind has used its intelligence to vary the flavour of drinks, which may be sweet, aromatic, fermented or spirit-based. ... Family and social life also offer numerous other occasions to consume drinks for pleasure. [Larousse, Drink entry] -- -- 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 --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.