随着我们添加更多约束,越来越明显我们需要指定更少的模板。不是
(defn -treec
([x fc cform] (-treec x fc cform nil))
([x fc cform _id]
(reify
clojure.lang.IFn
(invoke [this a]
(let [x (walk a x)]
(if (tree-term? x)
((composeg
(constrain-tree x
(fn [t a] ((treec t fc cform) a)))
(remcg this)) a)
((composeg
(fc x)
(remcg this)) a))))
IConstraintId
(id [this] _id)
IWithConstraintId
(with-id [this _id]
(-treec x fc cform _id))
IConstraintOp
(rator [_] `treec)
(rands [_] [x])
IReifiableConstraint
(reifyc [_ v r a]
(let [x (walk* r x)]
`(treec ~x ~cform)))
IRelevant
(-relevant? [_ a] true)
IRunnable
(runnable? [_ a]
(not (lvar? (walk a x))))
IConstraintWatchedStores
(watched-stores [this] #{::subst}))))
(defn treec [x fc cform]
(cgoal (-treec x fc cform)))
我们应该能够简单地编写
(defc treec [x fc cform]
clojure.lang.IFn
(invoke [this a]
(let [x (walk a x)]
(if (tree-term? x)
((composeg
(constrain-tree x
(fn [t a] ((treec t fc cform) a)))
(remcg this)) a)
((composeg
(fc x)
(remcg this)) a))))
IConstraintRands
(rands [_] [x])
IReifiableConstraint
(reifyc [_ v r a]
(let [x (walk* r x)]
`(treec ~x ~cform))))
`defc` 应该智能地填写细节。