复制的定义不足

Kim*_*son 3 haskell

我有一个问题,我认为相当棘手.

标准前奏包含该功能

replicate :: Int -> a -> [a]
Run Code Online (Sandbox Code Playgroud)

以下看起来似乎是一个合理的定义

replicate n x = take n [x,x,..]
Run Code Online (Sandbox Code Playgroud)

但实际上这还不够.为什么不?

我知道该replicate函数定义为:

replicate        :: Int -> a -> [a]       
replicate n x    =  take n (repeat x)
Run Code Online (Sandbox Code Playgroud)

repeat定义为:

repeat           :: a -> [a]  
repeat x         =  xs where xs = x:xs
Run Code Online (Sandbox Code Playgroud)

定义是否不充分(来自问题),因为它使用无限列表?

Wil*_*sem 5

首先,问题中存在一个小的语法错误,它应该是:

replicate n x = take n [x,x..]
--                         ^ no comma
Run Code Online (Sandbox Code Playgroud)

但是,我们不要挑剔.

现在当你使用范围语法(即x..)时,那么x应该是一个类型的实例Enum.确实:

Prelude> :t \n x -> take n [x,x..]
\n x -> take n [x,x..] :: Enum a => Int -> a -> [a]
Run Code Online (Sandbox Code Playgroud)

你可以说x,x..只会生成x,但Haskell编译器在编译时并不知道.

因此,在类型replicate(在这个问题)是太具体:它意味着一种约束- Enum a-这实际上是没有必要的.

另一方面,你自己的定义是完全正确的.Haskell对无限列表没有问题,因为它使用了惰性求值.此外,由于您定义xsxs作为尾,你真正构建循环链表这也是在内存使用方面更好.