【问题标题】:make [(Matrix Double,Vector Double)] an instance of Num使 [(Matrix Double,Vector Double)] 成为 Num 的一个实例
【发布时间】:2016-11-25 09:28:01
【问题描述】:

我定义了:

type Network = [(Matrix Double,Vector Double)]

其中 Matrix 和 Vector 来自 hmatrix 库。从 hmatrix 的文档来看,在我看来 Matrix Double 和 Vector Double 已经是 Num 的实例。由于我需要添加和减去 Networks quiet 很多,我还希望 Network 成为 Num 的一个实例。我试过了

instance Num Network where
  (+) = zipWith (\(m,v) (n,w) -> (m+n,v+w))
  (-) = zipWith (\(m,v) (n,w) -> (m-n,v-w))
  (*) = zipWith (\(m,v) (n,w) -> (m*n,v*w))

但我收到错误:非法实例声明。

【问题讨论】:

  • 您需要打开FlexibleInstances 语言扩展来创建基于类型同义词的实例,就像您编写的那样。 GHC 错误消息甚至可能暗示这一点(与TypeSynonymInstaces 一起,尽管FlexibleInstnaces 暗示前者)。
  • @AlexisKing:你能把它作为答案吗?它实际上回答了问题,并且具有更好的可见性。
  • 请不要这样做。这不是一个好主意。向量不是数字;逐元素乘法没有对一般向量有意义的语义。几乎可以肯定,也不适用于网络。不过,给它一个VectorSpace 实例可能很有意义,但你绝对应该将它包装在newtype 中。
  • 请注意,当您定义一个实例时,您应该定义所有类的操作。这包括例如signumabs。不这样做可能会导致您的程序崩溃,因为某些代码实际上使用了这些代码,它们最终会变成undefined

标签: haskell


【解决方案1】:

Alexis King 的评论对于编译您当前的代码是正确的。但是,为Network 创建一个newtype 可能是更好的做法——这样您根本不需要使用任何语言扩展。

newtype Network = Network [(Matrix Double,Vector Double)]

instance Num Network where
  (Network n1) + (Network n2) = Network $ zipWith (\(m,v) (n,w) -> (m+n,v+w)) n1 n2
  (Network n1) - (Network n2) = Network $ zipWith (\(m,v) (n,w) -> (m-n,v-w)) n1 n2
  (Network n1) * (Network n2) = Network $ zipWith (\(m,v) (n,w) -> (m*n,v*w)) n1 n2

【讨论】:

  • 感谢您的回答。网络的作用是什么?
  • newtype 在功能上 almostdata 相同,但只有一个具有一个字段的构造函数。您可以将Network 视为这种类型的构造函数。
  • @AndyM 为什么应该这样。什么错字!已更正。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-11-27
  • 1970-01-01
  • 1970-01-01
  • 2015-07-23
相关资源
最近更新 更多