复制功能由列表理解实现

时间:2013-11-26 18:30:19

标签: haskell

我正在学习Haskell,我试图自己实现replicate函数,下面是我工作的结果:

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

但在将脚本加载到ghci期间,我收到了msg:

proginhaskell.hs:152:29:
Could not deduce (Num a) arising from the literal `1'
from the context (Enum a)
  bound by the type signature for
             replicate' :: Enum a => a -> b -> [b]
  at proginhaskell.hs:152:1-34
Possible fix:
  add (Num a) to the context of
    the type signature for replicate' :: Enum a => a -> b -> [b]
In the expression: 1
In the expression: [1 .. a]
In a stmt of a list comprehension: _ <- [1 .. a]

我想问一下如何修复这个问题。这是实现复制功能的正确方法吗?

2 个答案:

答案 0 :(得分:5)

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

1 :: Num a => a -- Numbers are actually polymorphic!

所以GHC抱怨你没有说aNum个实例。因此,您只需在Num上的约束中添加a

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

至于这段代码有多好,我可能会用take编写它,但两者都是很好的实现。如果你很好奇它是如何实际实现的(尽管有更严格的replicate :: Int -> a -> [a]

replicate n x = take n (repeat x)

答案 1 :(得分:2)

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