Haskell にある関数を Scheme で書いてみた。
init
Haskell
Prelude Data.List> init [1,2,3,4,5] [1,2,3,4]
Scheme
(define init (lambda (lis) (take lis (- (length lis) 1)))) (print (init '(1 2 3 4 5)))
^o^ > gosh init.scm (1 2 3 4)
inits
Haskell
Prelude Data.List> inits [1,2,3,4,5] [[],[1],[1,2],[1,2,3],[1,2,3,4],[1,2,3,4,5]]
Scheme
(define inits (lambda (lis) (define f (lambda (n m l) (cond ((< n m) (quote ())) (else (cons (take l m) (f n (+ m 1) l)))))) (f (length lis) 0 lis))) (print (inits '(1 2 3 4 5)))
^o^ > gosh inits.scm (() (1) (1 2) (1 2 3) (1 2 3 4) (1 2 3 4 5))
tail
Haskell
Prelude Data.List> tail [1,2,3,4,5] [2,3,4,5]
Scheme
(define tail cdr) (print (tail '(1 2 3 4 5)))
^o^ > gosh tail.scm (2 3 4 5)
tails
Haskell
Prelude Data.List> tails [1,2,3,4,5] [[1,2,3,4,5],[2,3,4,5],[3,4,5],[4,5],[5],[]]
Scheme
(define tails (lambda (lis) (cond ((null? lis) (cons '() '())) (else (cons lis (tails (cdr lis))))))) (print (tails '(1 2 3 4 5)))
^o^ > gosh tails.scm ((1 2 3 4 5) (2 3 4 5) (3 4 5) (4 5) (5) ())
上のように、うまくいってるように見える Scheme の tails だけど、インタラクティブモードで定義して評価してやると変な値が返ってくる。
^o^ > gosh gosh> (define tails (lambda (lis) (cond ((null? lis) (cons '() '())) (else (cons lis (tails (cdr lis))))))) tails gosh> (tails '(1 2 3 4 5)) ((1 . #0=(2 . #1=(3 . #2=(4 . #3=(5))))) #0# #1# #2# #3# ())
最後の行が (tails '(1 2 3 4 5))
の変な値。
ところが、これを (print ...)
としてやるとちゃんとした値が出力される。
gosh> (print (tails '(1 2 3 4 5))) ((1 2 3 4 5) (2 3 4 5) (3 4 5) (4 5) (5) ()) #<undef>
どういうこと?