Are pattern matching or polymorphic dispatch available as conditional structures in clojure?

In a static language, I can replace conditional with polymorphism .

In languages ​​like erlang, I can use pattern matching instead of if else.

What can i use in clojure?

+4
source share
2 answers

You want to use multimethods. This is a great article explaining how to use them. http://adambard.com/blog/structured-clojure-protocols-and-multimethods/

(def speed 24)

(defmulti get-speed :type)

(defmethod get-speed :european       [_] speed)
(defmethod get-speed :african        [_] (+ speed 2))
(defmethod get-speed :norwegian-blue [_] (* speed 1.05))

(get-speed {:type :european}) 
; => 200
+7
source

Both pattern matching and polymorphic dispatch are available.

Two forms of polymorphic sending are dots and protocols.

leontalbot , ( , ). , , multimethod .

:

; Declare multimethod:
(defmulti get-length class)

; Provide implementations for concrete types:
(defmethod get-length java.lang.String [str] (.length str))
(defmethod get-length java.lang.Number [num] (.length (str num)))

; Call it for String:
(get-length "Hello") ;=> 5

; Call it for a Number (works because Long is a subtype of Number):
(get-length 1234) ;=> 4

, , . , :

(defn choose-impl [in]
  (cond
    (is-sorted? in) :sorted
    (< (count in) 10) :bubble
    :else :quicksort))

(defmulti my-sort choose-impl)

(defmethod my-sort :sorted [in] in)

(defmethod my-sort :bubble [in] (my-bubble-sort in))

(defmethod my-sort :quicksort [in] (my-quicksort in))

, , , , , .

- , , Java OO. , , .

; Protocol specification:
(defprotocol my-length (get-length [x]))

; Records can implement protocols:
(defrecord my-constant-record [value]
  my-length
    (get-length [x] value))

; We can "extend" existing types to support the protocol too:
(extend-protocol my-length
  java.lang.String
    (get-length [x] (.length x))
  java.lang.Long
    (get-length [x] (.length (.toString x))))

; Now calling get-length will find the right implementation for each:
(get-length (my-constant-record. 15)) ;=> 15

(get-length "123") ;=> 3

(get-length 1234) ;=> 4

, core.match:

(doseq [n (range 1 101)]
  (println
    (match [(mod n 3) (mod n 5)]
      [0 0] "FizzBuzz"
      [0 _] "Fizz"
      [_ 0] "Buzz"
      :else n)))
+9

Source: https://habr.com/ru/post/1547927/


All Articles