Guest User

Untitled

a guest
Jun 23rd, 2018
80
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.39 KB | None | 0 0
  1. (ns coarse.cats)
  2.  
  3. (defn pure [x]
  4. [:pure x x])
  5.  
  6. (defn pure? [v]
  7. (and (vector? v)
  8. (> (count v) 0)
  9. (= (first v) :pure)))
  10.  
  11.  
  12. (defn classify-type [x]
  13. (if-let [t (:type x)]
  14. t
  15. (cond
  16. (fn? x) :fn
  17. (pure? x) :pure
  18. (coll? x) :coll)))
  19.  
  20. (defn mk-identity [x]
  21. {:type :identity :value x})
  22.  
  23. (defn mk-const [x]
  24. {:type :const :value x})
  25.  
  26. (defn mk-first [x]
  27. {:type :first :value x})
  28.  
  29. (defn mk-tuple [a b]
  30. {:type :tuple :value [a b]})
  31.  
  32. (defn just [x]
  33. {:value x :type :maybe})
  34.  
  35. (def nothing {:value nil :type :maybe})
  36.  
  37. (defn nothing? [x]
  38. (nil? (:value x)))
  39.  
  40. (defn spoon [x]
  41. (if (nil? x)
  42. nothing
  43. (just x)))
  44.  
  45. (defn cons'
  46. ([x xs] (cons x (if (pure? xs) (second xs) xs)))
  47. ([x] (partial cons' x)))
  48.  
  49. (defn lift-pure [t [_ v o]]
  50. (if (= t :const)
  51. {:value [] :type t}
  52. {:value v :type t}))
  53.  
  54. (defmulti fmap (fn [x y] (classify-type y)))
  55.  
  56. (defmulti app (fn [x y]
  57. (if (pure? x)
  58. (classify-type y)
  59. (classify-type x))))
  60.  
  61. (defn traverse
  62. ([f ta]
  63. (if (empty? ta)
  64. (pure [])
  65. (let [x (first ta)
  66. xs (rest ta)
  67. fm' (fmap cons' (f x))
  68. lt' (traverse f xs)
  69. fm (if (and (pure? fm') (:type lt'))
  70. (lift-pure (:type lt') fm')
  71. fm')
  72. lt (if (and (pure? lt') (:type fm'))
  73. (lift-pure (:type fm') lt')
  74. lt')]
  75. (app fm lt))))
  76. ([f]
  77. (partial traverse f)))
  78.  
  79. (def mempty :mempty)
  80.  
  81. (defmulti mappend (fn [x y]
  82. (if (= x mempty)
  83. (classify-type y)
  84. (classify-type x))))
  85.  
  86.  
  87. (defmethod mappend :coll
  88. [a b]
  89. (cond
  90. (= a mempty) b
  91. (= b mempty) a
  92. :else (concat a b)))
  93.  
  94. (defn implicit-lift-first [a]
  95. (if (= a mempty) (mk-first nothing) a))
  96.  
  97. (defmethod mappend :first
  98. [a b]
  99. (cond
  100. (= a mempty) (implicit-lift-first b)
  101. :else (implicit-lift-first a)))
  102.  
  103. (defn rest' [a]
  104. (if (pure? a) [] (rest a)))
  105.  
  106. (defmethod app :maybe
  107. [f m']
  108. (let [m (if (pure? m') (just (second m')) m')]
  109. (if (or (nothing? f) (nothing? m))
  110. nothing
  111. (just ((:value f) (:value m))))))
  112.  
  113. (defmethod app :coll
  114. [fs l']
  115. (let [l (if (pure? l') [(second l')] l')]
  116. (if (empty? l)
  117. []
  118. (apply concat
  119. (for [f fs]
  120. (mapv f l))))))
  121.  
  122. (defmethod app :identity
  123. [a' b']
  124. (let [a (if (pure? a') (mk-identity (second a')) a')
  125. b (if (pure? b') (mk-identity (second b')) b')]
  126. (mk-identity ((:value a) (:value b)))))
  127.  
  128. (defn lift-list [x]
  129. (if (coll? x)
  130. x
  131. [x]))
  132.  
  133. (defmethod app :pure
  134. [[_ a x] [_ b y]]
  135. (let [v1 (if (coll? a) (mk-identity a) (mk-const []))
  136. v2 (if (coll? a) (mk-identity b) (mk-const []))]
  137. (if (coll? a)
  138. (mk-identity [])
  139. (mk-const []))))
  140.  
  141. (defmethod app :const
  142. [f v']
  143. (let [v (if (pure? v') (mk-const mempty) v')]
  144. (mk-const (mappend (:value f) (:value v)))))
  145.  
  146. (defmethod fmap :pure
  147. [f [_ v o]]
  148. [:pure (f v) o])
  149.  
  150. (defmethod fmap :identity
  151. [f {:keys [value]}]
  152. (mk-identity (f value)))
  153.  
  154. (defmethod fmap :coll
  155. [fv coll]
  156. (mapv fv coll))
  157.  
  158. (defmethod fmap :maybe
  159. [f m]
  160. (if (nothing? m)
  161. m
  162. (just (f (:value m)))))
  163.  
  164. (defmethod fmap :const
  165. [f v]
  166. v)
  167.  
  168. (defmethod fmap :tuple
  169. [f {:keys [value]}]
  170. (let [[a b] value]
  171. (mk-tuple a (f b))))
  172.  
  173. (defn pure-from [t ele]
  174. (case t
  175. :const (mk-const [])
  176. :identity (mk-identity ele)
  177. :first (mk-first (just ele))
  178. (pure ele)))
Add Comment
Please, Sign In to add comment