复制功能由列表理解实现

MC2*_*2DX 2 haskell

我正在学习Haskell,我试图自己实现这个replicate功能,下面是我工作的结果:

replicate' :: Enum a => a -> b -> [b]
replicate' a b = [b | _ <- [1..a]]
Run Code Online (Sandbox Code Playgroud)

但在加载脚本到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]
Run Code Online (Sandbox Code Playgroud)

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

Dan*_*zer 5

问题是你正在使用列表表达式[1..a],这意味着我们必须能够将其1视为同一类型a.类型1

1 :: Num a => a -- Numbers are actually polymorphic!
Run Code Online (Sandbox Code Playgroud)

所以GHC抱怨你没有说这a是一个Num实例.所以你可以添加Num你的约束a.

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

至于这段代码有多好,我可能会写它take,但两者都是很好的实现.如果你很好奇它是如何实际实现的(虽然限制更多replicate :: Int -> a -> [a])

replicate n x = take n (repeat x)
Run Code Online (Sandbox Code Playgroud)