Rewrite strategy combinators.
A strategy is a unary function of a term (any object) and returns the term rewritten.
Notation:
t ∈ Term p, q, r, s ∈ Strategy
Rewrite strategy combinators. A strategy is a unary function of a term (any object) and returns the term rewritten. Notation: t ∈ Term p, q, r, s ∈ Strategy
(all-bu s)Apply the all strategy with s to every subterm in t from the
bottom up.
Apply the all strategy with `s` to every subterm in `t` from the bottom up.
(all-td s)Apply the all strategy with s to every subterm in t from the
top down.
Apply the all strategy with `s` to every subterm in `t` from the top down.
(at key)(at key p)(at key p q)(at key p q & more)(at k & ps)Build a strategy which modifies t at key with p, then q, etc. Works with map?, vector?, and set?. For vector? and set? key must be present.
Build a strategy which modifies t at key with p, then q, etc. Works with map?, vector?, and set?. For vector? and set? key must be present.
(attempt s)Build a strategy which attempts apply s to a term. If s
succeeds, it returns the result. If s fails return the original
term.
Build a strategy which attempts apply `s` to a term. If `s` succeeds, it returns the result. If `s` fails return the original term.
(bottom-up s)Build a strategy which applies s to each subterm of t from
bottom to top.
Build a strategy which applies `s` to each subterm of `t` from bottom to top.
(breadth-first s)Build a strategy which applies s to each subterm of t in a
breadth-first order.
Build a strategy which applies `s` to each subterm of `t` in a breadth-first order.
(build t)Build a strategy which always returns t.
Build a strategy which always returns `t`.
(choice)(choice p)(choice p q)(choice p q & more)(choice)(choice p)(choice p q)(choice p q r)(choice p q r s)(choice p q r s & more)Build a strategy which applies p or q to t. If p rewrites,
return the result, otherwise apply q.
Build a strategy which applies `p` or `q` to `t`. If `p` rewrites, return the result, otherwise apply `q`.
(extract s)Return a sequence of all successful rewrites of s applied to all subterms of t.
Return a sequence of all successful rewrites of s applied to all subterms of t.
(fail? x)true if x is *fail*, false otherwise.
true if `x` is `*fail*`, false otherwise.
(find & clauses)Strategy version of meander.match.epsilon/find that defaults to returning fail.
Strategy version of meander.match.epsilon/find that defaults to returning *fail*.
(fix s)Return a strategy which applies the strategy s to a term t
repeatedly until it the result of applying s its argument returns
its argument.
(def to-pair
  (fix (rewrite
         [?x ?y]
         [?x ?y]
         ?x
         [?x ?x])))
(to-pair [1 2])
;; => [1 2]
(to-pair 1)
;; => [1 1]
Return a strategy which applies the strategy `s` to a term `t`
repeatedly until it the result of applying `s` its argument returns
its argument.
    (def to-pair
      (fix (rewrite
             [?x ?y]
             [?x ?y]
             ?x
             [?x ?x])))
    (to-pair [1 2])
    ;; => [1 2]
    (to-pair 1)
    ;; => [1 1](guard p s)Build a strategy which applies s to t iff p is true for t.
Build a strategy which applies `s` to `t` iff `p` is true for `t`.
(innermost s)Build a strategy which repeatedly applies s to t starting from
the innermost subterm in t.
Build a strategy which repeatedly applies `s` to `t` starting from the innermost subterm in `t`.
(match & clauses)Strategy version of match which defaults to returning fail.
Strategy version of match which defaults to returning *fail*.
(n-times n s)Builds a strategy that repeats the passed in strategy n times.
This is particularly useful for non-terminating rewrites or
when you are trying to write a strategy and want to make sure you
don't accidentally infinite loop.
((n-times 2 (rewrite ?x (?x ?x))) :x) ;; => ((:x :x) (:x :x))
Builds a strategy that repeats the passed in strategy `n` times. This is particularly useful for non-terminating rewrites or when you are trying to write a strategy and want to make sure you don't accidentally infinite loop. ((n-times 2 (rewrite ?x (?x ?x))) :x) ;; => ((:x :x) (:x :x))
(once-bu s)Apply the one strategy with s to every subterm in t from the
bottom up.
Apply the `one` strategy with `s` to every subterm in `t` from the bottom up.
(once-td s)Apply the one strategy with s to every subterm in t from the
top down.
Apply the `one` strategy with `s` to every subterm in `t` from the top down.
(outermost s)Build a strategy which repeatedly applies s to t starting from
the outermost subterm in t until it fails.
Build a strategy which repeatedly applies `s` to `t` starting from the outermost subterm in `t` until it fails.
(pass? x)true if x is *pass*, false otherwise.
true if `x` is `*pass*`, false otherwise.
(pipe)(pipe p)(pipe p q)(pipe p q & more)(pipe)(pipe p)(pipe p q)(pipe p q r)(pipe p q r s)(pipe p q r s & more)Build a strategy which applies p to t and then q iff p rewrites
t. If p and q are successful, return the result, otherwise
return *fail*.
Build a strategy which applies `p` to `t` and then `q` iff `p` rewrites `t`. If `p` and `q` are successful, return the result, otherwise return `*fail*`.
(pred p)Build a strategy which returns t iff p is true for t and
fails otherwise.
Build a strategy which returns `t` iff `p` is true for `t` and fails otherwise.
(repeat s)Build a strategy which applies s to t repeatedly until failure.
Note that, if used in conjunction with a strategy which never fails
i.e. attempt, this will cause a stack overflow. To avoid this, use
while or until.
Example:
((repeat (pipe (pred vector?) (fn [v] (if (seq v) (if (= (peek v) 2) fail (pop v)) fail)))) [1 2 3 4]) ;; => [1 2]
Build a strategy which applies `s` to `t` repeatedly until failure.
Note that, if used in conjunction with a strategy which never fails
i.e. `attempt`, this will cause a stack overflow. To avoid this, use
`while` or `until`.
Example:
((repeat
  (pipe (pred vector?)
        (fn [v]
          (if (seq v)
            (if (= (peek v) 2)
              *fail*
              (pop v))
            *fail*))))
 [1 2 3 4])
;; =>
[1 2]
(retain s)(retain s t)Return a strategy which retains subterms of t for which the strategy s succeeds.
Return a strategy which retains subterms of t for which the strategy s succeeds.
(rewrite & rules)Returns strategy which symbolically transforms t in to t* via
pattern matching and substitution. Pattern matching is conducted
using find.
Example:
(let [s (rewrite (let* [!bs !vs ..1] . !body ...) (let* [!bs !vs] (let* [!bs !vs ...] . !body ...)))] (s '(let* [b1 :v1, b2 :v2, b3 :v3] (vector b1 b2 b3)))) ;; => (let* [b1 :v1] (let* [b2 :v2 b3 :v3] (vector b1 b2 b3)))
Returns strategy which symbolically transforms `t` in to `t*` via
pattern matching and substitution. Pattern matching is conducted
using `find`.
Example:
(let [s (rewrite
         (let* [!bs !vs ..1]
           . !body ...)
         (let* [!bs !vs]
           (let* [!bs !vs ...]
             . !body ...)))]
  (s '(let* [b1 :v1, b2 :v2, b3 :v3]
        (vector b1 b2 b3))))
  ;; =>
  (let* [b1 :v1]
    (let* [b2 :v2
           b3 :v3]
      (vector b1 b2 b3)))(search & clauses)Strategy version of search.
Strategy version of search.
(some s)Build a strategy which applies s to as many direct subterms of
t as possible. Succeeds if at least one application applies, fails
otherwise.
Build a strategy which applies `s` to as many direct subterms of `t` as possible. Succeeds if at least one application applies, fails otherwise.
(some-bu s)Return a strategy which attempts to apply the strategy s to all
subterms of a term t from the bottom-up (post-order). Succeeds if
at least one subterm of t passed to s succeeds, fails otherwise.
(def inc-numbers
  (some-td (pipe (pred number?) inc)))
(inc-numbers [1 ["2" 3] "4"])
;;=> [2 ["2" 4] "4"]
(inc-numbers ["1" "2"])
;; => #meander.epsilon/fail[]
Return a strategy which attempts to apply the strategy `s` to all
subterms of a term `t` from the bottom-up (post-order). Succeeds if
at least one subterm of `t` passed to `s` succeeds, fails otherwise.
    (def inc-numbers
      (some-td (pipe (pred number?) inc)))
    (inc-numbers [1 ["2" 3] "4"])
    ;;=> [2 ["2" 4] "4"]
    (inc-numbers ["1" "2"])
    ;; => #meander.epsilon/fail[](some-td s)Return a strategy which attempts to apply the strategy s to all
subterms of a term t from the top-down (pre-order). Succeeds if at
least one subterm of t passed to s succeeds, fails otherwise.
(def inc-numbers
  (some-td (pipe (pred number?) inc)))
(inc-numbers [1 ["2" 3] "4"])
;;=> [2 ["2" 4] "4"]
(inc-numbers ["1" "2"])
;; => #meander.epsilon/fail[]
Return a strategy which attempts to apply the strategy `s` to all
subterms of a term `t` from the top-down (pre-order). Succeeds if at
least one subterm of `t` passed to `s` succeeds, fails otherwise.
    (def inc-numbers
      (some-td (pipe (pred number?) inc)))
    (inc-numbers [1 ["2" 3] "4"])
    ;;=> [2 ["2" 4] "4"]
    (inc-numbers ["1" "2"])
    ;; => #meander.epsilon/fail[](spread f)(spread f n)Build a strategy which applies the first n values of t to f
iff t is a coll. Behaves like apply if n is not supplied. Useful
in conjunction with juxt.
((pipe (tuple (comp (some keyword) keys) vals) (spread zipmap 2)) {"foo" "bar" "baz" "quux"}) ;; => {:foo "bar" :baz "quux"}
Build a strategy which applies the first `n` values of `t` to `f`
iff `t` is a coll. Behaves like apply if `n` is not supplied. Useful
in conjunction with `juxt`.
((pipe
  (tuple (comp (some keyword) keys)
         vals)
  (spread zipmap 2))
 {"foo" "bar"
  "baz" "quux"})
;; =>
{:foo "bar"
 :baz "quux"}(top-down s)Build a strategy which applies s to each subterm of t from
top to bottom.
Build a strategy which applies `s` to each subterm of `t` from top to bottom.
(top-down-until pred s)Build a strategy which applies s to each subterm of t from
top to bottom until pred is false for some subterm of t.
Build a strategy which applies `s` to each subterm of `t` from top to bottom until `pred` is false for some subterm of `t`.
(top-down-while pred s)Build a strategy which applies s to each subterm of t from
top to bottom so long as pred is true for some subterm of t.
Build a strategy which applies `s` to each subterm of `t` from top to bottom so long as `pred` is true for some subterm of `t`.
(trace s)(trace s f)Build a strategy which monitors the entry and exit values of s.
Build a strategy which monitors the entry and exit values of `s`.
(tuple)(tuple p)(tuple p q)(tuple p q & more)(tuple)(tuple p)(tuple p q)(tuple p q r)(tuple p q r s)(tuple p q r s & more)Build a strategy which behaves similarly to juxt but fails if any
of the strategies which compose it fail.
Build a strategy which behaves similarly to `juxt` but fails if any of the strategies which compose it fail.
(until pred s)Build a strategy which repeatedly applies s to t so long as pred
is false for t and t*.
((until = (rewrite ('let [!bs !vs ... ?b ?v] . !body ...) ('let [!bs !vs ...] (('fn [?b] . !body ...) ?v))
  ('let [] ?x)
  ?x))
'(let [a 1 b 2 c 3] (+ a b c))) ;; => ((fn [a] ((fn [b] ((fn [c] (+ a b c)) 3)) 2)) 1)
Build a strategy which repeatedly applies `s` to `t` so long as `pred`
is false for `t` and `t*`.
  ((until =
     (rewrite
      ('let [!bs !vs ... ?b ?v]
       . !body ...)
      ('let [!bs !vs ...]
       (('fn [?b]
         . !body ...)
        ?v))
      ('let [] ?x)
      ?x))
   '(let [a 1
          b 2
          c 3]
      (+ a b c)))
  ;; =>
  ((fn [a] ((fn [b] ((fn [c] (+ a b c)) 3)) 2)) 1)(while pred s)Build a strategy which repeatedly applies s to t so long as pred
is false for t and t*.
((while not= (rewrite ('let [!bs !vs ... ?b ?v] . !body ...) ('let [!bs !vs ...] (('fn [?b] . !body ...) ?v))
  ('let [] ?x)
  ?x))
'(let [a 1 b 2 c 3] (+ a b c))) ;; => ((fn [a] ((fn [b] ((fn [c] (+ a b c)) 3)) 2)) 1)
Build a strategy which repeatedly applies `s` to `t` so long as `pred`
is false for `t` and `t*`.
  ((while not=
     (rewrite
      ('let [!bs !vs ... ?b ?v]
       . !body ...)
      ('let [!bs !vs ...]
       (('fn [?b]
         . !body ...)
        ?v))
      ('let [] ?x)
      ?x))
   '(let [a 1
          b 2
          c 3]
      (+ a b c)))
  ;; =>
  ((fn [a] ((fn [b] ((fn [c] (+ a b c)) 3)) 2)) 1)
cljdoc builds & hosts documentation for Clojure/Script libraries
| Ctrl+k | Jump to recent docs | 
| ← | Move to previous article | 
| → | Move to next article | 
| Ctrl+/ | Jump to the search field |