Haskell-需要为类型类定义Vector2实例 [英] Haskell - need to define Vector2 instance for typeclass
问题描述
newtype Vector2 a = Vector2 (a,a)
deriving (Show,Eq)
class VectorSpace v where
vZero :: (Num a) => v a
vSum :: (Num a) => v a -> v a -> v a
vScalarProd :: (Num a) => a -> v a -> v a
vMagnitude :: (Floating a) => v a -> a
需要将Vector2定义为类型VectorSpace的实例.
Need to define for Vector2 to be instances of the type class VectorSpace.
推荐答案
所以这是我到目前为止尝试过的:
So here is what I tried so far:
instance VectorSpace (a,a) => VectorSpace Vector2 a
vecZero = (0.0,0.0)
vecSum (x,y) (x',y') = (x+x',y+y')
这里的第一个问题是语法.在第一行的末尾需要一个where
,如果Vector2 a
应该是实例头,则需要在括号中加上
The first problem here is syntax. You need a where
at the end of the first line, and if Vector2 a
is supposed to be the instance head then it needs to go in parentheses:
instance VectorSpace (a,a) => VectorSpace (Vector2 a) where
但是,这与声明的类的类型不匹配.
That, however, doesn't match the kinds of your declared class.
class VectorSpace (v :: * -> *) where
vZero :: (Num a) => v a
...
即,该类已经具有内置的假设,即将v
应用于某些a
参数†.因此,实例头应该不包含该参数,它看起来应该像
i.e., the class already has the assumption built in that v
will be applied to some a
parameter†. Thus the instance head should not contain that parameter, it should just look like
instance (...?) => VectorSpace Vector2 where
实际上,您在这里根本不需要任何约束.
In fact it turns out you don't need any constraints at all here.
instance VectorSpace Vector2 where
关于方法,
vecSum (x,y) (x',y') = (x+x',y+y')
如果您的类型是元组类型,那将是一个非常明智的实现.但是,您的类型实际上是newtype
包装的元组,并且newtypes
始终需要显式构造函数.喜欢
that would be a perfectly sensible implementation if your type were the tuple type. However your type is actually a newtype
wrapped tuple, and newtypes
always need explicit constructors. Like
vecSum (Vector2 (x,y)) (Vector2 (x',y')) = Vector2 (x+x',y+y')
这确实有点愚蠢:您同时嵌套了一个命名构造函数和一个元组构造函数.由于元组会导致额外的间接访问(惰性,缓存),因此效率也相当低下.该类型最好定义为
This is a bit silly really: you have both a named constructor and a tuple constructor, nested. It's also pretty inefficient since tuples incur extra indirection (laziness, cache). The type should better be defined as
data Vector2 a = Vector2 !a !a
在这里,由于字段很严格,GHC可以将数字拆箱.在这种情况下,定义为
where, because the fields are strict, GHC can unbox the numbers. In that case, the definition would be
vecSum (Vector2 x y) (Vector2 x' y') = Vector2 (x+x') (y+y')
† Mind,正如我已经评论过的,对于向量空间类完全参数化v a
来说,IMO 不好不好.在 vector-space
库,不需要实例化参数;优点之一是您可以直接为普通元组提供实例,而无需任何新类型包装.
†Mind, as I've already commented it is IMO not good for a vector space class to parameterise v a
at all. In the vector-space
library, the instances aren't required to be parameterised; one of the advantages is that you can directly give an instance for ordinary tuples without needing any newtype wrapping.
这篇关于Haskell-需要为类型类定义Vector2实例的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!