Skip to content

Instantly share code, notes, and snippets.

@zobar
Created July 27, 2015 16:43
Show Gist options
  • Select an option

  • Save zobar/9688832d01ed01331629 to your computer and use it in GitHub Desktop.

Select an option

Save zobar/9688832d01ed01331629 to your computer and use it in GitHub Desktop.
Encapsulation without objects
(ns functor
(:refer-clojure :exclude [map]))
(defprotocol Functor
"Defines functor/Functor"
(map [functor f]))
(defn each
[functor f]
(map functor f)
functor)
(ns safe
(:require [functor])
(:refer-clojure :exclude [map]))
(defn failure
[error]
(reify functor/Functor
(map [functor _]
functor)
(toString [_]
(str "Failure " error))))
(defn success
[val]
(reify functor/Functor
(map [_ f]
(success (f val)))
(toString [_]
(str "Success " val))))
(defn map
[functor f]
(functor/map functor #(try (success (f %))
(catch Exception e (failure e)))))
(ns maybe
(:require functor safe))
(def nothing
(reify functor/Functor
(map [functor _]
functor)
(toString [_]
"Nothing")))
(defn just
[val]
(reify functor/Functor
(map [_ f]
(just (f val)))
(toString [_]
(str "Just " val))))
(safe/map nothing println)
;=> #<user$reify__838 Nothing>
(safe/map (just "poo") #(str % \space %))
;=> #<user$just$reify__840 Just Success poo poo>
(safe/map (just "pee") #(throw (Exception. %)))
;=> #<user$just$reify__840 Just Failure java.lang.Exception: pee>
(functor/map (just "fart") #(throw (Exception. %)))
;=> Exception fart sun.reflect.NativeConstructorAccessorImpl.newInstance0 (NativeConstructorAccessorImpl.java:-2)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment