【问题标题】:No instance for (Num p) arising from a use of `+' [duplicate]没有因使用“+”而产生 (Num p) 的实例 [重复]
【发布时间】:2019-04-05 22:08:51
【问题描述】:

如果我从 GHCi 终端执行 myZipWith (+) (Point [1,2,3]) (Point [4,5,6]) 一切正常,但如果我尝试从一个简单的函数执行它,则会出现错误。

为什么即使代码相同,直接从终端执行却不一样?

这是我的代码:

data Point p = Point [p]
deriving (Show)

wtf :: [p]
wtf = myZipWith (+) (Point [1,2,3]) (Point [4,5,6])

myZip :: Point p -> Point p -> [(p, p)]
myZip (Point []) _ = []
myZip _ (Point []) = []
myZip (Point (a:as)) (Point (b:bs)) = (a, b) : myZip (Point as) (Point bs)


myZipWith :: (p -> p -> p) -> Point p -> Point p -> [p]
myZipWith f (Point p1) (Point p2) = [ f (fst x) (snd x) | x <- (myZip (Point p1) (Point p2)) ]

错误代码:

No instance for (Num p) arising from a use of `+'
      Possible fix:
        add (Num p) to the context of
          the type signature for:
            wtf :: forall p. [p]
    * In the first argument of `myZipWith', namely `(+)'
      In the expression:
        myZipWith (+) (Point [1, 2, 3]) (Point [4, 5, 6])
      In an equation for `wtf':
          wtf = myZipWith (+) (Point [1, 2, 3]) (Point [4, 5, 6])

【问题讨论】:

    标签: haskell types ghci


    【解决方案1】:

    您已定义 wtf 以适用于 任何 类型 p,而不仅仅是具有 Num 实例的类型。您需要在类型注释中包含约束。

    wtf :: Num p => [p]
    wtf = myZipWith (+) (Point [1,2,3]) (Point [4,5,6])
    

    这是建议的可能修复所暗示的解决方案(即,“将 [ing] Num p 添加到类型签名的上下文中”)。 myZipmyZipWith 不需要注释,因为没有任何关于它们的 Num-特定。只有使用(+) :: Num a =&gt; a -&gt; a -&gt; awtf的定义需要额外的约束。

    如果你放弃了类型注解,只写了wtf = myZipWith (+) (Point [1,2,3]) (Point [4,5,6]),那么Haskell 就会推断出列表的类型Num a =&gt; [a]。您的明确、过于笼统的类型阻止了推理的发生。

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-04
    相关资源
    最近更新 更多