添加到其他答案,
由于show
返回 a java.lang.String
,因此无法显示无限列表。所以我想我可以写一个不同版本的 show 来返回 a [Char]
。这就是我想出的,它正在发挥作用。
frege> :paste
class AltShow a where
altshow :: a -> [Char]
instance AltShow AltShow a => [a] where
altshow [] = []
altshow xs = concat $ (['['] : intersperse [','] ys) ++ [[']']] where
ys = map altshow xs
instance AltShow Int where
altshow = unpacked <~ show
intersperse :: a -> [a] -> [a]
intersperse _ [] = []
intersperse _ (x:[]) = [x]
intersperse sep (x : y : []) =
x : sep : y : []
intersperse sep (x : y : rest) =
x : sep : y : sep : intersperse sep rest
:q
Interpreting...
frege> altshow [1, 10, 2, 234]
res3 = ['[', '1', ',', '1', '0', ',', '2', ',', '2', '3', '4', ']']
frege> :t res3
res5 :: [Char]
frege> packed res3
res6 = [1,10,2,234]
frege> :t res6
res7 :: String
现在问题中的代码变得类似于 Haskell,并且不会因 OutOfMemoryError 而爆炸:
frege> :paste
foo = take 10 $ altshow $ numbersFrom 1 where
numbersFrom start = start : numbersFrom (start + 1)
:q
Interpreting...
frege> foo
res9 = ['[', '1', ',', '2', ',', '3', ',', '4', ',', '5']
frege> packed foo
res11 = [1,2,3,4,5