Drop+first+line

言及されてたので解説。
ソースはこんな感じ。

(load "./lazier.scm")
(load "./prelude.scm")

(lazy-def '(main input)
  '(input
    (lambda (hd tl)
      (((hd (lambda (x) (x (k i))) (k i)) cdr) tl))))

(print-as-unlambda (laze 'main))

やりたいことは、

  • 先頭文字 (hd) が改行なら、2文字目以降 (tl) を返す。
  • 先頭文字 (hd) が'a'なら、3文字目以降 ( (cdr tl) ) を返す。

です。cheat上等。

hdが先頭文字のchurch数なので、式の初めの部分は

(hd (lambda (x) (x (k i))) (k i))
=> (…(((k i) (k i)) (k i)) … (k i))

と、(k i) に (k i) を(先頭文字のASCIIコード)回適用したものになります。

(k i) の並びは奇数個なら (k i)、偶数個なら i になります。

  (k i)               => (k i)
 ((k i) (k i))        => i
(((k i) (k i)) (k i)) => (i (k i)) => (k i)

なので、hdが偶数の場合(先頭文字が改行)は

(((hd (lambda (x) (x (k i))) (k i)) cdr) tl)
=> (((k i) cdr) tl) => (i tl) => tl

hd が奇数の場合(先頭文字が'a')は

(((hd (lambda (x) (x (k i))) (k i)) cdr) tl)
=> ((i cdr) tl) => (cdr tl)

となります。