Skip to content

Commit

Permalink
Migrated generic.functor
Browse files Browse the repository at this point in the history
  • Loading branch information
khinsen committed Oct 8, 2011
1 parent 2143dd1 commit 1381315
Show file tree
Hide file tree
Showing 2 changed files with 96 additions and 0 deletions.
39 changes: 39 additions & 0 deletions src/main/clojure/clojure/algo/generic/functor.clj
@@ -0,0 +1,39 @@
;; Generic interface for functors

;; by Konrad Hinsen

;; Copyright (c) Konrad Hinsen, 2009-2011. All rights reserved. The use
;; and distribution terms for this software are covered by the Eclipse
;; Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php)
;; which can be found in the file epl-v10.html at the root of this
;; distribution. By using this software in any fashion, you are
;; agreeing to be bound by the terms of this license. You must not
;; remove this notice, or any other, from this software.

(ns
^{:author "Konrad Hinsen"
:doc "Generic functor interface (fmap)"}
clojure.algo.generic.functor)


(defmulti fmap
"Applies function f to each item in the data structure s and returns
a structure of the same kind."
{:arglists '([f s])}
(fn [f s] (type s)))

(defmethod fmap clojure.lang.IPersistentList
[f v]
(map f v))

(defmethod fmap clojure.lang.IPersistentVector
[f v]
(into (empty v) (map f v)))

(defmethod fmap clojure.lang.IPersistentMap
[f m]
(into (empty m) (for [[k v] m] [k (f v)])))

(defmethod fmap clojure.lang.IPersistentSet
[f s]
(into (empty s) (map f s)))
57 changes: 57 additions & 0 deletions src/test/clojure/clojure/algo/generic/test_functor.clj
@@ -0,0 +1,57 @@
;; Test routines for clojure.algo.generic.collection

;; Copyright (c) Konrad Hinsen, 2011. All rights reserved. The use
;; and distribution terms for this software are covered by the Eclipse
;; Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php)
;; which can be found in the file epl-v10.html at the root of this
;; distribution. By using this software in any fashion, you are
;; agreeing to be bound by the terms of this license. You must not
;; remove this notice, or any other, from this software.

(ns clojure.algo.generic.test-functor
(:use [clojure.test :only (deftest is are run-tests)])
(:require [clojure.algo.generic.functor :as gf])
(:require [clojure.algo.generic.collection :as gc]))

; Test implementations for CLojure's built-in collections
(deftest builtin-collections
(are [a b] (= a b)
(gf/fmap inc (list 1 2 3)) (list 2 3 4)
(gf/fmap inc [1 2 3]) [2 3 4]
(gf/fmap inc {:A 1 :B 2 :C 3}) {:A 2 :B 3 :C 4}
(gf/fmap inc #{1 2 3}) #{2 3 4}))


; Define a multiset class. The representation is a map from values to counts.
(defrecord multiset [map])

(defn mset
[& elements]
(gc/into (new multiset {}) elements))

; Implement the collection multimethods.
(defmethod gc/conj multiset
([ms x]
(let [msmap (:map ms)]
(new multiset (assoc msmap x (inc (get msmap x 0))))))
([ms x & xs]
(reduce gc/conj (gc/conj ms x) xs)))

(defmethod gc/empty multiset
[ms]
(new multiset {}))

(defmethod gc/seq multiset
[ms]
(apply concat (map (fn [[x n]] (repeat n x)) (:map ms))))

; Implement fmap
(defmethod gf/fmap multiset
[f m]
(gc/into (gc/empty m) (map f (gc/seq m))))

; Multiset tests
(deftest multiset-tests
(are [a b] (= a b)
(gf/fmap inc (mset 1 2 3)) (mset 2 3 4)))

0 comments on commit 1381315

Please sign in to comment.