Haskell - need to define Vector2 instance for typeclass

后端 未结 1 879
野性不改
野性不改 2021-01-29 15:23
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
          


        
相关标签:
1条回答
  • 2021-01-29 16:13

    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')

    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
        ...

    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
    

    Now as for the methods,

      vecSum (x,y) (x',y') = (x+x',y+y')

    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
    

    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, 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.

    0 讨论(0)
提交回复
热议问题