我正在学习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]
我想问一下如何修复这个问题。这是实现复制功能的正确方法吗?
答案 0 :(得分:5)
问题是您使用的是列表表达式[1..a]
,这意味着我们必须能够将1
视为与a
相同的类型。 1
的类型是
1 :: Num a => a -- Numbers are actually polymorphic!
所以GHC抱怨你没有说a
是Num
个实例。因此,您只需在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
具有相同的类型。由于1
是Num
,因此a
应为Num
类型。因此,您应该Enum a
作为上下文而不是(Enum a, Num a)
。