我想知道将类Haskell的数据类型翻译为Scheme的最佳方法是什么。我的当前计划是使用vector
来表示构造器,第一个元素是代表变体的label
。例如,下面是一个Haskell程序:
data Bits = O Bits | I Bits | E deriving Show
data Nat = S Nat | Z deriving Show
inc (O pred) = I pred
inc (I pred) = O (inc pred)
inc E = E
dup (S pred) = let (x,y) = dup pred in (S x, S y)
dup Z = (Z, Z)
bus Z bs = inc bs
bus (S pred) bs = let (x,y) = (pred,pred) in (bus pred (bus pred bs))
o32 = (O (O (O (O (O (O (O (O (O (O (O (O (O (O (O (O (O (O (O (O (O (O (O (O (O (O (O (O (O (O (O (O E))))))))))))))))))))))))))))))))
n26 = (S (S (S (S (S (S (S (S (S (S (S (S (S (S (S (S (S (S (S (S (S (S (S (S (S (S Z))))))))))))))))))))))))))
main = print (bus n26 o32)
Would be translated as:
(define (O pred) (vector 'O pred))
(define (I pred) (vector 'I pred))
(define E (vector 'E))
(define (S pred) (vector 'S pred))
(define Z (vector 'Z))
(define (Inc bits) (case (vector-ref bits 0) ('O (I (vector-ref bits 1))) ('I (O (Inc (vector-ref bits 1)))) ('E E)))
(define (Dup val) (case (vector-ref val 0) ('S (let ((xy (Dup (vector-ref val 1)))) (cons (S (car xy)) (S (cdr xy))))) ('Z (cons Z Z))))
(define (Bus n bs) (case (vector-ref n 0) ('Z (Inc bs)) ('S (let ((xy (Dup (vector-ref n 1)))) (Bus (car xy) (Bus (cdr xy) bs))))))
(define O32 (O (O (O (O (O (O (O (O (O (O (O (O (O (O (O (O (O (O (O (O (O (O (O (O (O (O (O (O (O (O (O (O E)))))))))))))))))))))))))))))))))
(define N26 (S (S (S (S (S (S (S (S (S (S (S (S (S (S (S (S (S (S (S (S (S (S (S (S (S (S Z)))))))))))))))))))))))))))
(display (Bus N26 O32))
令我惊讶的是,这个方法表现得非常好(Scheme在这里比Haskell更快)。但我想知道这是否是最好的方法?这种做法合理吗,还是有更加“惯用”的翻译方式,能够表现得更好吗?