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>
どういうこと?