Haskell-需要为类型类定义Vector2实例 [英] Haskell - need to define Vector2 instance for typeclass

查看:70
本文介绍了Haskell-需要为类型类定义Vector2实例的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆