Haskellの表記をGaucheと併せて比べてみる。
まずは、shiroさんに教えてもらったGaucheのコード*1
(use util.match) (define qsort (match-lambda (()()) ((x . xs) (receive (l r) (partition (cut < <> x) xs) `(,@(qsort l) ,x ,@(qsort r))))))
次になるべく似せたHaskellのコード
import List qsort [] = [] ; qsort (x:xs) = (\y->(qsort $ fst y)++[x]++(qsort $ snd y)) $ partition (\y->y<x) xs
partitionの受けが多値かタプルの違いと準クオートぐらいか。
こうやって並べるとリスト内包表記はすごいんだな。
qsort [] = [] ; qsort (x:xs) = qsort[y|y<-xs,y<x]++[x]++qsort[y|y<-xs,y>=x]
まあ、こうやって比較していくのはいいことだ。いろんな勉強ができる。
*1:やっとそらでかけるようになった(涙
Gaucheでリスト内包表現にチャレンジ(まずは..)
まだマクロが全然わかってないんだがとりあえずやってみたい気持ちが先行中(笑)
ということで実装してみたのがこれ。
>>(define .. (lambda (x y) (let ((e (- y x -1))) (if (< e 0) () (iota e x))))) =>.. >>(.. 0 10) =>(0 1 2 3 4 5 6 7 8 9 10) >>(.. -1 -10) =>() >>(.. -10 -1) =>(-10 -9 -8 -7 -6 -5 -4 -3 -2 -1)
うーん。ここまではhaskellと同じだが、嫌な予感がした小数はどう動く?
Prelude List> [1.1..1.5] [1.1] Prelude List> [1.1,1.2..1.5] [1.1,1.2,1.2999999999999998,1.3999999999999997,1.4999999999999996]
なんだよ、この動きは無視しちゃおうかな。
次にやらなければならないのは [1..3]みたいな個別括弧なんだろうが…なんか実験してると全ての括弧は()の代用品になる?
>>{car '{1 2 3}} =>1 >>[car '[1 2 3]] =>1
ねえ、全部予約なの(笑)
どうしてくれよう。マクロでこんなことができるのか興味が湧いてきた。
いかんその前に増分[1,3..10]=>[1,3,5,7,9]に対応しなきゃ
>>(define .. (lambda (x y . z) (let* ((s (if (null? z) 1 (- y x))) (e (if (null? z) y (car z)))) (if (< e 0) () (iota e x s))))) =>.. >>(.. 1 2 10) =>(1 2 3 4 5 6 7 8 9 10) >>(.. 1 3 10) =>(1 3 5 7 9 11 13 15 17 19)
こりゃへこむな。10までって意味だもんな。終了条件変えなきゃいけないので自前でつくるか。明日にしよう。
とりあえず、filterで着陸したのが以下(cut大活躍)
>>(define .. (lambda (x y . z) (let* ((s (if (null? z) 1 (- y x))) (e (if (null? z) y (car z)))) (if (< e 0) () (filter (cut <= <> e) (iota e x s)))))) =>.. >>(.. 1 2 10) =>(1 2 3 4 5 6 7 8 9) >>(.. 1 3 10) =>(1 3 5 7 9)
追記:filterやめてみたが美しくない。
>>(define .. (lambda (x y . z) (let* ((s (if (null? z) 1 (- y x))) (e (quotient (- (if (null? z) y (car z)) x -1) s))) (if (< e 0) () (iota e x s)))))