Hi MK-list, I'm trying all kinds of nasty-hackery stuff in my mk 
implementation.  
I want to share this one.
Maybe some one already came up with this.

Use case: Pattern matching/destructuring a cons.
In order to destructure a list I tend to create fresh vars for matching the 
head and the tail of the list.

(defn some-goal [alist]
  (fresh [h t]
    (conso h t alist) ;; if alist is actually a pair/list then h and t are 
introduce only for capture, 
    (conde [(some-goal-onhead  h)]
                [(some-goal-ontail t)])) 

This may introduce h and t into the substitution. But it can be avoided 
with using continuations-ish form.

(defn match-lcons [maybe-alist fun]
  (fn [a] 
       (let [maybe-alist (walk maybe-alist a)]
           (cond 
              (pair? maybe-alist) (fun (car maybe-alist) (cdr maybe-alist))
              (lvar? maybe-alist) (fresh [ h t ] 
                                                   (conso h t maybe-alist)
                                                   (fun h t))
               :else                       u#)))

Now i can write the original example as:

(defn some-goal [alist]
  (match-lcons alist 
       (fn [h t]
         (conde [(some-goal-onhead  h)]
                     [(some-goal-ontail t)]))) 

And it will introduce lvars only when they are actually needed.

Cheers.

-- 
You received this message because you are subscribed to the Google Groups 
"minikanren" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
Visit this group at https://groups.google.com/group/minikanren.
For more options, visit https://groups.google.com/d/optout.

Reply via email to