newtype Vector2 a = Vector2 (a,a)
deriving (Show,Eq)
instance VectorSpace Vector2 where
vecMagnitude (Vector2 (a,b)) = (a**2 + b**2)**(1/2)
vecF :: (Floating a, VectorSpace v) => v a -> [v a] -> [a]
vecF Vector2 (a,b) ys = [ vecMagnitude ( Vector2 (a+(-1)*a'),(b+(-1)*b') ) |(a',b') <- ys ]
所以上面的编码我有错误,是vecF函数,请参见以下错误msg:
Couldn't match type ‘v’ with ‘(,) a0’
‘v’ is a rigid type variable bound by
the type signature for:
vecF :: forall a (v :: * -> *).
(Floating a, VectorSpace v) =>
v a -> [v a] -> [a]
at Assign_2_EC_test.hs:74:1-58
Expected type: v a
Actual type: (a0, a)
In the pattern: (a, b)
In an equation for ‘vecF’:
vecF (a, b) ys
= [vecMagnitude ((a + (- 1) * a'), (b + (- 1) * b')) |
(a', b') <- ys]
Relevant bindings include
vecF :: v a -> [v a] -> [a]
任何主意是什么错误
答案 0 :(得分:4)
这里基本上存在四个问题:两个可以轻松解决,其他则需要更改签名或实现额外的功能:
您忘记在函数的开头写括号:
vecF (Vector2 (a,b)) ys = ...
列表理解中“ yield”部分的方括号没有构成元组的方括号:
[ vecMagnitude (Vector2 (a+(-1)*a', b+(-1)*b')) | ... ]
在您的签名中,允许第一个参数为v a
类型为v
,VectorSpace
类型为a
的任何Floating
,因此,您不能只添加如下构造函数:
vecF (Vector2 (a, b)) = ...
(无法直接解决),因为ys
是v a
的列表,所以不能仅从ys
枚举为:
[ ... | (a', b') <- ys ]
最后两个问题不能轻易解决,我们可以专门化签名以使其起作用,例如:
vecF :: Floating a => Vector2 a -> [(a, a)] -> [a]
vecF (Vector2 (a,b)) ys = [ vecMagnitude ( Vector2 (a-a',b-b')) |(a',b') <- ys ]
但是我们当然可以灵活地松动以使用其他VectorSpace
,例如,另一种选择是将vecF
移至class
定义并在{{1}中实现}子句。最后,另一个选择可能是提供额外的功能,这样您就不需要模式匹配来计算instance
,例如,您可以实现一个功能:
vecMaginute
然后您可以将其实现为:
class VectorSpace v where
-- ...
vecDiff :: Num a => v a -> v a -> v a