Cyanのリスト操作
リテラルのリストの操作は色々短く書けてよさげ。
Lispとの対応
- [a | b] -> (a . b)
- [a, b] -> (a b)
- [*a, b] -> `(,@a b)
*(Expander)が便利。
cyan> a=[1,2,3] => [1, 2, 3] cyan> [0|a] => [0, 1, 2, 3] cyan> [*a,4] => [1, 2, 3, 4] cyan> b=a.map^(n):n+4 => [5, 6, 7] cyan> [0,*a,4|b] => [0, 1, 2, 3, 4, 5, 6, 7]
+演算子がないのはちょっと不便。でも自分で書いてしまえば。
cyan> a+b (stdin):2: error: invalid message for [1, 2, 3]: (+) cyan> def(List.(+))^(l):[*self|l] => ^(self, l){ [*self | l] } cyan> a+[4]+b+[]+[8]+9 => [1, 2, 3, 4, 5, 6, 7, 8 | 9] cyan> iota(4,[],'[a,b]) => [[], [a, b], [a, b, a, b], [a, b, a, b, a, b]]
標準でfilterはあるけど、removeとpartitionがないのでゴルフ風味で書いてみる。
[].remove=^(_,p):[] def(List.remove)^(p): $(x,r):=&(.car(),.cdr().remove(p)) p(x)&&r||[x|r] [].partition=^(_,p):&([],[]) def(List.partition)^(p): $(x,a,b):=&(.car(),*.cdr().partition(p)) p(x)&&&([x|a],b)||&(a,[x|b])
partitionを使ってquicksort
[].qsort=^(_,f):[] def(List.qsort)^(f): x:=.car() $(l,r):=.cdr().partition^(n):f n,x [*l.qsort(f),x|r.qsort(f)]
cyan> iota(20).remove^(n):n.rem(3)>0 => [0, 3, 6, 9, 12, 15, 18, 19] cyan> iota(10).partition^(n):n.rem(2)==0 => &([0, 2, 4, 6, 8], [1, 3, 5, 7, 9]) cyan> [2, 5, 1, 32, 5, 10].qsort^(x, y){ x < y } => [1, 2, 5, 5, 10, 32]
quicksortが1,2行で書けないとブレイクできないらしいけど、Cyanのリスト表記は好きだなー。