在列表中创建类型类的实例时遇到问题

时间:2016-03-04 06:02:53

标签: haskell computer-science typeclass

我创建了一个类型类,并列出了类型类的实例,但是我收到了一个我不明白的错误

class MyType a where
listsum:: a->a->Double

instance (Num a)=>MyType [a] where
    listsum x y = sum $ zipWith (-) x y 

listsum返回单个值,但这是我得到的错误:

 Could not deduce (a ~ Double)
from the context (Num a)
  bound by the instance declaration at b2.hs:4:10-28
  `a' is a rigid type variable bound by
      the instance declaration at b2.hs:4:10
In the expression: sum $ zipWith (-) x y
In an equation for `listsum': listsum x y = sum $ zipWith (-) x y
In the instance declaration for `MyType [a]'
Failed, modules loaded: none.

我该如何解决这个问题?

2 个答案:

答案 0 :(得分:2)

让我们写下一些注释。

sum     :: (Num a, Foldable t) => t a -> a
zipWith :: (a -> b -> c) -> [a] -> [b] -> [c]
(-)     :: Num a => a -> a -> a

让我们推导出\ x y -> sum $ zipWith (-) x y的类型。

-- 1. Let's substitute (-) to zipWith:

zipWith (-) :: Num a => [a] -> [a] -> [a]

-- 2. Let's substitute `(zipWith (-))` to `sum`. We can't
-- write it point free like in `zipWith (-)` case. So we add
-- two extra params:

(\ x y -> sum $ zipWith (-) x y) :: Num a => [a] -> [a] -> a

listsum的{​​{1}}类型为:

[a]

它需要listsum :: (Num a) => [a] -> [a] -> Double (Num a => a)两个列表 返回Double。但是(\ x y -> sum $ zipWith (-) x y) 返回任何(Num a => a)。编译器无法确定 此(Num a => a)始终为Double。这就是你的原因 得到错误:

Could not deduce (a ~ Double) from the context (Num a)

@sclv为您提供了两个解决方案。另一个是 将MyType类更改为

class MyType a where
    listsum:: [a] -> [a] -> a

以便listsum(\ x y -> sum $ zipWith (-) x y)具有相同的类型。

它还为您提供了通过列表元素参数化listsum的机会。

答案 1 :(得分:1)

您可以将listsum:: a -> a -> Double修改为listsum :: [a] -> [a] -> a并将您的实例声明为a而不是[a] 您可以从{修改您的实例{1}}至instance (Num a) => MyType [a]

只需获取表达式instance MyType [Double]的类型即可看到错误。您会看到,您的班级目前需要\x y -> sum $ zipWith (-) x y而不是Num a => [a] -> [a] -> a