Hatena::Groupcadr

わだばLisperになる このページをアンテナに追加 RSSフィード

2004 | 12 |
2005 | 01 | 02 | 07 | 10 | 11 |
2006 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2007 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2008 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2009 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2010 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2011 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 11 |

2008-06-24

pfcでL-99 (P12 ランレングス圧縮の伸長)

| 16:14 | pfcでL-99 (P12 ランレングス圧縮の伸長) - わだばLisperになる を含むブックマーク はてなブックマーク - pfcでL-99 (P12 ランレングス圧縮の伸長) - わだばLisperになる

なんとなく無理矢理な感じですが、折角の遅延評価なので使ってみました。

(decode '((4 A) B (2 C) (2 A) D (4 E)))
;==> [A A A A B C C A A D E E E E]

(define (decode lst)
  (if (null lst)
      ()
      (let ((head (hd lst)))
        (++ (if (atom head)
                [head]
                (take (hd head)
                      (item-list (hd (tl head)))))
            (decode (tl lst))))))

(define (item-list item)
  (cons item (item-list item)))

2008-06-16

pfcでL-99 (P11 ランレングス圧縮 その2)

| 18:08 | pfcでL-99 (P11 ランレングス圧縮 その2) - わだばLisperになる を含むブックマーク はてなブックマーク - pfcでL-99 (P11 ランレングス圧縮 その2) - わだばLisperになる

ポール・グレアムで有名なsingleを定義して使ってみました。

(encode-modified '(a a a a b c c a a d e e e e))
;=> [[4 a] b [2 c] [2 a] d [4 e]]

(define (single? lst)
  (and [(consp lst)
        (null (tl lst))]))

(define (encode-modified lst)
  (map (lambda (x) 
         (if (single? x)
             (hd x)
             [(length x) (hd x)]))
       (pack lst)))

2008-06-12

pfcでL-99 (P10 ランレングス圧縮)

| 15:58 | pfcでL-99 (P10 ランレングス圧縮) - わだばLisperになる を含むブックマーク はてなブックマーク - pfcでL-99 (P10 ランレングス圧縮) - わだばLisperになる

これもまた普通のLISP/Schemeみたいになってしまいました…。

(encode '(a a a a b c c a a d e e e e))
;==> [[4 a] [1 b] [2 c] [2 a] [1 d] [4 e]]

(define (encode lst)
  (map (lambda (x) [(length x) (hd x)])
       (pack lst)))

2008-06-04

pfcでL-99 (P09 連続して現われる要素を纏める)

| 04:20 | pfcでL-99 (P09 連続して現われる要素を纏める) - わだばLisperになる を含むブックマーク はてなブックマーク - pfcでL-99 (P09 連続して現われる要素を纏める) - わだばLisperになる

うーん、これだ!というようなpfcでの良い書き方がありそうな気がする問題ではあるのですが、全然思い付けません。

(pack '(a a a a b c c a a d e e e e))
;==> [[a a a a] [b] [c c] [a a] [d] [e e e e]]

(define (pack lst)
  (if (null lst)
      ()
      (pack1 lst () ())))

(define (pack1 lst tem res)
  (let ((head (hd lst))
        (tail (tl lst)))
    (if (consp tail)
        (if (= head (hd tail))
            (pack1 tail 
                   (++ [head] tem)
                   res)
            (pack1 tail 
                   ()
                   (++ res [(cons head tem)])))
        (++ res [(cons head tem)]))))

2008-05-26

pfcでL-99 (P08 連続する要素を圧縮)

| 11:57 | pfcでL-99 (P08 連続する要素を圧縮) - わだばLisperになる を含むブックマーク はてなブックマーク - pfcでL-99 (P08 連続する要素を圧縮) - わだばLisperになる

pfcでは、可変長引数がないので、andもCLでいうeveryのようなものになっているようです。

(compress '(a a a a b c c a a d e e e e))
;==>[a b c a d e]

(define (compress lst)
  (if (null? lst)
      ()
      ((if (and [(consp (tl lst)) (= (hd lst) (hd (tl lst)))])
           (lambda (x) x)
           (cons (hd lst)))
       (compress (tl lst)))))

pfcでL-99 (P07 リストの平坦化)

| 11:57 | pfcでL-99 (P07 リストの平坦化) - わだばLisperになる を含むブックマーク はてなブックマーク - pfcでL-99 (P07 リストの平坦化) - わだばLisperになる

なんだか無理矢理ですが、折角なのでカリー化してみました。

(flatten '((0 (1 ((((2 (((((3 (((4)))))))) 5))))) (6 (7 8) 9))))
;=> [0 1 2 3 4 5 6 7 8 9]

(define (flatten lst)
  (if (null? lst)
      ()
      ((if (atom (hd lst))
           (cons (hd lst))
           (++ (flatten (hd lst))))
       (flatten (tl lst)))))

2008-05-13

pfcでL-99 (P06 リストが回文的かを判定)

| 23:41 | pfcでL-99 (P06 リストが回文的かを判定) - わだばLisperになる を含むブックマーク はてなブックマーク - pfcでL-99 (P06 リストが回文的かを判定) - わだばLisperになる

ううむ。もっと先の問題にならないとpfcならでは、というところが見えてこないのかもしれない…。

前回定義したrevを使用。

(palindrome? '(x a m a x))
;=> #t

(def (palindrome? lst)
  (= (rev lst) lst))

2008-05-06

pfcでL-99 (P05 リストを反転させる)

| 12:49 | pfcでL-99 (P05 リストを反転させる) - わだばLisperになる を含むブックマーク はてなブックマーク - pfcでL-99 (P05 リストを反転させる) - わだばLisperになる

pfcでは、appendを++とも書けるようです。listがないので、[]で囲んでいます。

(def (rev lst)
  (if (null lst)
      ()
      (++ (rev (tl lst)) [(hd lst)])))

2008-04-29

pfcでL-99 (P04 リストの長さ)

| 00:50 | pfcでL-99 (P04 リストの長さ) - わだばLisperになる を含むブックマーク はてなブックマーク - pfcでL-99 (P04 リストの長さ) - わだばLisperになる

そもそもpfcの特長をあまり把握していないので、普通にscheme的なものとして書いてしまうなあ…。

pfcにはlengthが備え付けで存在しています。

(len '(1 2 3 4))
;=> 4

(def (len lst)
  (if (null lst)
      0
      (1+ (len (tl lst)))))

2008-04-22

pfcでL-99 (P03 K番目の要素)

| 02:48 | pfcでL-99 (P03 K番目の要素) - わだばLisperになる を含むブックマーク はてなブックマーク - pfcでL-99 (P03 K番目の要素) - わだばLisperになる

pfcには、condがないようなので、ifの組み合わせで書いてみました。

;(element-at '(a b c d e) 100)
;=> c

(def (element-at lst k)
  (if (null lst) 
      ()
      (if (>= 1 k)
          (hd lst)
          (element-at (tl lst) (1- k)))))

2008-04-13

pfcでL-99 (P02 最後2つの要素)

| 19:43 | pfcでL-99 (P02 最後2つの要素) - わだばLisperになる を含むブックマーク はてなブックマーク - pfcでL-99 (P02 最後2つの要素) - わだばLisperになる

自分は毎回混乱しているのですが、2番目の問題は、最後2つの要素を取り出す問題です。

標準でdropがあるので、それを使ってみました。

dropはSRFI-1由来だと思いますが、CLだと、LASTがdropの代わりに使えます。

(last '(1 2 3 4) 2) => (3 4)

(last2 [1 2 3 4])
;=> [3 4]

(def (last2 lst)
  (drop (- (length lst) 2) lst))

(def (last2 lst)
  (if (>= 2 (length lst))
      lst
      (last2 (cdr lst))))

2008-04-12

pfcでL-99 (P01 最後のペアを返す)

| 07:38 | pfcでL-99 (P01 最後のペアを返す) - わだばLisperになる を含むブックマーク はてなブックマーク - pfcでL-99 (P01 最後のペアを返す) - わだばLisperになる

なんとなく面白そうだったので、pfcでも、L-99に挑戦してみることにしました。

GaucheのWilikiのページで、letzf等の内包表記が使える処理系ということで知ったのですが、処理系探してもずっと見付けられないでいました。

処理系の名前がどうやら、pfcらしいということが分かって、pfcで検索していたらGaucheのLingr部屋のログに配布先があったので、ソースを入手して試してみました。

ソースは、Darcsで入手できます。

darcs get http://www.sampou.org/repos/pfc

srcディレクトリの中で、makeすれば、pfcの実行ファイルが生成されますので、それを実行します。

ドキュメントはないようですが、電通大の岩崎教授が中心となって、Haskell/Schemeで有名な山下氏、伊東氏が開発に参加している処理系のようです。

まだ良く分かっていないのですが、標準で遅延評価やambがあったりするようです。

pfcでの関数定義は、Schemeと同じようなのですが、defineの代わりにdefも使えるようで、MIT記法もあります。

リスト、タプル/ベクタ

リストはCL/Schemeと違ってGOOのように真性リストしかないようです。

ドット対リストに相当するものは、(pair 1 1) =>{1 1}のように作る様子。要素にはfstとsndでアクセスでQiのタプルと同じ感じ。

また、(list 1 2 3)の代わりに、[1 2 3]と書くところもQiに似ています。

細々したこと

null ≡ null?、cdr ≡ tl(tailから?)、car ≡ hd(headから?)、cons? ≡ consp等、MacLISP系の関数名とScheme畑や関数言語畑の名前が好みに応じて使えるようです。

(my-last '(a b c d))
;=> (d)

(def (my-last lst)
  (if (null (tl lst))
      lst
      (my-last (tl lst))))

(def (my-last lst)
  (drop (1- (length lst)) lst))

(def (my-last lst)
  [((! lst) (1- (length lst)))])

;; ~~~
(index '(0 1 2 3) 0) ; or (! '(0 1 2 3) 0)
;=> 0

(let ((!lst (! '(0 1 2 3))))
  (!lst 0))
;=> 0