Haskell 通过列表理解实现的复制功能

Haskell 通过列表理解实现的复制功能,haskell,Haskell,我正在学习Haskell,并尝试自己实现replicate功能,以下是我工作的结果: replicate' :: Enum a => a -> b -> [b] replicate' a b = [b | _ <- [1..a]] replicate':枚举a=>a->b->[b] 复制'AB=[b | a->b->[b] 在proginhaskell.hs:152:1-34 可能的解决方案: 将(Num a)添加到 复制“”的类型签名:枚举a=>a->b->[b] 在

我正在学习Haskell,并尝试自己实现
replicate
功能,以下是我工作的结果:

replicate' :: Enum a => a -> b -> [b]
replicate' a b = [b | _ <- [1..a]]
replicate':枚举a=>a->b->[b]
复制'AB=[b | a->b->[b]
在proginhaskell.hs:152:1-34
可能的解决方案:
将(Num a)添加到
复制“”的类型签名:枚举a=>a->b->[b]
在表达式中:1
在表达式中:[1..a]

在列表理解的stmt中:问题是您使用的是列表表达式
[1..a]
,这意味着我们必须能够将
1
视为与
a
相同的类型

1 :: Num a => a -- Numbers are actually polymorphic!
所以GHC抱怨你没有说
a
Num
实例。所以你可以在
a
的约束中添加
Num

replicate' :: (Enum a, Num a) => a -> b -> [b]
replicate' a b = [b | _ <- [1..a]]

从这段代码
[1..a]
编译器推断
a
应该与
1
具有相同的类型。由于
1
Num
,因此
a
应该是
Num
类型。因此,您应该将
作为上下文,而不是
枚举a
(枚举a,Num a)

“至于这段代码有多好,我可能会用显式递归编写它,以避免生成无用的列表,但两者都是很好的实现。”-我相信GHC能够优化这种情况,并摆脱
[1..a]生成的列表
。看。@PedroRodrigues我很好奇并分析了核心,似乎两者都编译成了相同的代码,最后我更喜欢前奏曲
take
。我相应地编辑了我的答案
replicate' :: (Enum a, Num a) => a -> b -> [b]
replicate' a b = [b | _ <- [1..a]]
replicate n x = take n (repeat x)