我刚刚从Haskell开始,我阅读了LYAH的定义数据类型部分,并试图实现求和-积算法的信念传播。最基本的任务之一是定义概率图形模型。
如下图所示,我试图通过打结来创建一个图,以表示每个节点表示一个高斯分布的图形,并且(就目前而言)与它的邻居有固定的权重链接。但是,当试图定义均值和协方差类型时,我很难指定矩阵和向量类型的类型,即浮点数或双值类型。
module Graph(Graph) where
import Numeric.LinearAlgebra
data Mean = Mean Vector
data Covariance = Covariance Matrix
data Gaussian = Gaussian Mean Covariance
data Node = Node [Node] Gaussian
data Graph = Graph [Node]在这个简单的例子中,用什么语法来定义Mean作为Double类型的向量,将协方差定义为类型Double的矩阵。此外,如何进行概括,使Mean和Covariance可以是浮动或双类型的呢?
我目前从GHCi获得以下信息
Graph.hs:5:18: error:
• Expecting one more argument to ‘Vector’
Expected a type, but ‘Vector’ has kind ‘* -> *’
• In the type ‘Vector’
In the definition of data constructor ‘Mean’
In the data declaration for ‘Mean’
Failed, modules loaded: none.我使用的h矩阵包,如所描述的这里
发布于 2017-03-25 14:25:05
Vector和Matrix是在标量类型上参数化的(因此不仅可以有浮点“实数”的矩阵,还可以有整数矩阵、复数矩阵等)。这是GHC通过‘Vector’ has kind ‘* -> *’告诉您的:Vector本身并不是一种类型(类型有样*,又名Type)。相反,它是将类*的类型映射到类*类型的类型函数。像Double这样的标量已经是普通类型,所以您只需将Vector应用于它们。
GHCi> :kind Vector
Vector :: * -> *
GHCi> :k Double
Double :: *
GHCi> :k Vector Double
Vector Double :: *所以你需要
newtype Mean = Mean (Vector Double)
newtype Covariance = Covariance (Matrix Double)(newtype在这里做的事情和data一样,但效率要高一些,因为不需要额外的框/指针)。
或者,您可以使用更有意义的向量空间,例如,
import Math.LinearMap.Category
newtype Mean v = Mean v
newtype Covariance v = Covariance (v +> DualVector v)这样做的优点是在编译时检查维度,这可以防止严重的运行时错误(原则上也可以提高性能,尽管坦率地说,linearmap-category库还没有被优化)。
然后,还可以参数化向量空间上的其他类型:
data Gaußian v = Gaußian (Mean v) (Covariance v)
data Node v = Node [Node v] (Gaussian v)
data Graph v = Graph [Node v]与您的问题有些无关:这种打结确实感觉很优雅,但是它并不是表示图的真正合适的方法,因为节点不能被标识检查。图中的任何循环都会导致无穷大的结构。在实践中,您将不会给出节点,例如Int标签和为边缘保留一个单独的结构。
https://stackoverflow.com/questions/43017384
复制相似问题