Last week I released a project with a monadic translator that needed to: - work on sequences of expressions, arbitrarily nested - generate Clojure code or stop and report the first error - maintain a symbol table with easy access but not global state
The relevant code is here: https://github.com/blancas/eisen/blob/master/src/main/clojure/blancas/eisen/trans.clj The code uses a StateT monad transformer and Either monad wrapped in five API functions: ->left, ->right, get-se, modify-se, run-se. Functions report errors with (->left); function (->right) wraps good values. The macro (monad) corresponds to Haskell's do; it chains monadic values or short-circuits and propagates errors. (defn trans-binop "Translates the application of a binary operator." [ast] (monad [x (trans-expr (:left ast)) y (trans-expr (:right ast))] (let [f (-> ast :op :value str symbol)] (->right `(~f ~x ~y))))) The symbol table is available through get-se and modify-se. A typical use case is to enter declared names, translate the expressions, then remove the names from the symbol table. (defn trans-let "Translates a let expression." [{:keys [decls exprs]}] (let [env (map (comp symbol :name) decls)] (monad [_ (modify-se into env) decls (trans-bindings decls) exprs (trans-exprs exprs) _ (modify-se difference env)] (->right `(let [~@(apply concat decls)] ~@exprs))))) To translate expressions in a sequence it uses the generic function (seqm); function (run-se) evaluates the resulting sequenced monads using an initial state "predefs". The result from (run-se) feeds (either) which evaluates to the first form on ->left and to the second on ->right. (let [job (monad [v (seqm (map eval-ast coll))] (->right v))] (either [res (run-se job predefs)] {:ok false :error res} {:ok true :decls (map first res) :value (-> res last second)}))) On Monday, April 8, 2013 7:56:35 AM UTC-7, Carlos Galdino wrote: > > Hi, > > I've been reading about monads for the past couple of weeks and I think I > got the idea, but I still don't know when to use it since I don't have > enough experience with functional programming. > > So, I'd like to ask you guys if you can point me to some examples of > Monads usage "in the wild". Because I've seen a lot of simple examples but > not a real one, used in a library, etc. > > Does anyone know a good example of real world usage? > > Thanks in advance. > -- -- 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.