Lisp のリストを表示する関数

Lisp のリストを表示する関数を作ってみた。


data Symbol = I Integer | S String | Nil | C Cell deriving (Show, Read, Eq)

data Cell = Cell { car_ :: Symbol, cdr_ :: Symbol} deriving (Show, Read, Eq)

cons a b = C Cell { car_ = a, cdr_ = b }

car (C cell) = car_ cell
cdr (C cell) = cdr_ cell

listToString ls = "(" ++ listToString_ ls ++ ")"
listToString_ Nil = ""
listToString_ ls = case (car ls) of
(C _) -> "(" ++ listToString_ (car ls) ++ ")(" ++ listToString_ (cdr ls)++")"
(I x) -> (show x) ++ (outSpace ls) ++listToString_ (cdr ls)
(S x) -> "\""++ x ++ "\"" ++ (outSpace ls) ++listToString_ (cdr ls)

outSpace ls = if (cdr ls)==Nil then "" else " "

cell = cons (S "World!") Nil
list1 = cons (S "Hello") cell
cell2 = cons (I 456) Nil
list2 = cons (I 123) cell2
list3 = cons list1 list2

main = do
putStrLn $ listToString cell
putStrLn $ listToString list1
putStrLn $ listToString list2
putStrLn $ listToString list3

*Main> cell
C (Cell {car_ = S "World!", cdr_ = Nil})
*Main> putStrLn $ listToString cell
("World!")
*Main> list1
C (Cell {car_ = S "Hello", cdr_ = C (Cell {car_ = S "World!", cdr_ = Nil})})
*Main> putStrLn $ listToString list1
("Hello" "World!")
*Main> list2
C (Cell {car_ = I 123, cdr_ = C (Cell {car_ = I 456, cdr_ = Nil})})
*Main> putStrLn $ listToString list2
(123 456)
*Main> list3
C (Cell {car_ = C (Cell {car_ = S "Hello", cdr_ = C (Cell {car_ = S "World!", cdr_ = Nil})}),
cdr_ = C (Cell {car_ = I 123, cdr_ = C (Cell {car_ = I 456, cdr_ = Nil})})})
*Main> putStrLn $ listToString list3
( ("Hello" "World!") (123 456))