我有一个问题,我认为相当棘手。
标准前奏包含功能
replicate :: Int -> a -> [a]
以下看起来似乎是一个合理的定义
replicate n x = take n [x,x,..]
但实际上还不够。为什么不呢?
我知道replicate
函数定义为:
replicate :: Int -> a -> [a]
replicate n x = take n (repeat x)
repeat
定义为:
repeat :: a -> [a]
repeat x = xs where xs = x:xs
定义是否不足(来自问题),因为它使用无限列表?
答案 0 :(得分:5)
首先,问题中存在一个小的语法错误,它应该是:
replicate n x = take n [x,x..]
-- ^ no comma
但是不要挑剔。
现在,当您使用范围语法(即x..
)时,x
应该属于Enum
的实例。事实上:
Prelude> :t \n x -> take n [x,x..]
\n x -> take n [x,x..] :: Enum a => Int -> a -> [a]
你可以说x,x..
只生成x
,但Haskell编译器在编译时不知道。
因此replicate
(问题中)中的类型太具体:它暗示了类型约束 - Enum a
- 实际上不是必要。
xs
定义为xs
作为尾部,您实际上构建了一个循环链表,在内存使用方面也更好。