David Nolen <[email protected]> writes:
> There's no easy way to do this beyond making your own relational
> string type as you've suggested.
FWIW, I had the same need as Adam and the poor-man's solution below is
enough for my use-case.
--8<---------------cut here---------------start------------->8---
(defn ground?
"Returns true, if `x` is ground.
`x` must have been `walk`ed before!"
[x]
(not (ccl/lvar? x)))
(defn ^:private str-splits [s]
(loop [idx 0, r []]
(if (<= idx (count s))
(recur (inc idx)
(conj r [(subs s 0 idx) (subs s idx)]))
r)))
(defn stro
([x y xy]
(fn [a]
(let [wx (cclp/walk a x)
wy (cclp/walk a y)
wxy (cclp/walk a xy)]
(cond
(and (ground? wx) (ground? wy) (ground? wxy))
(if (= (str wx wy) wxy) (ccl/succeed a) (ccl/fail a))
(and (ground? wx) (ground? wy))
(or (ccl/unify a xy (str wx wy))
(ccl/fail a))
(and (ground? wx) (ground? wxy) (string? wxy)
(.startsWith ^String wxy wx))
(or (ccl/unify a y (subs wxy (count wx)))
(ccl/fail a))
(and (ground? wy) (ground? wxy) (string? wxy)
(.endsWith ^String wxy wy))
(or (ccl/unify a x (subs wxy 0 (- (count wxy) (count wy))))
(ccl/fail a))
(ground? wxy)
(ccl/to-stream
(->> (map (fn [[s1 s2]]
(ccl/unify a [x y] [s1 s2]))
(str-splits wxy))
(remove not)))
;; TODO: we should not fail here...
:else (ccl/fail a)))))
([x y z xyz]
(ccl/fresh [front]
(ccl/conde
;; This one works if x and y are ground
[(stro x y front)
(stro front z xyz)]
;; This one works if xyz is ground
[(stro front z xyz)
(stro x y front)]))))
--8<---------------cut here---------------end--------------->8---
Of course it's not fully relational, but it's enough when you just need
to concatenate strings, or inversely, split strings at a certain
separator, e.g., full name <=> first name, last name.
Bye,
Tassilo
--
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to [email protected]
Note that posts from new members are moderated - please be patient with your
first post.
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
---
You received this message because you are subscribed to the Google Groups
"Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.