我刚开始学习Haskell而且遇到了麻烦 使用hmatrix库。我想写一些简单的代码 使用eigenvalue方法计算power iteration。 我从:
开始c = fromList [4.0, 4.0, 4.0, 4.0]::Vector Double
n = norm2 c
创建向量c并找到向量的2范数。
与c
相乘:
c * 2 (Works)
c * 0.5 (Works)
c * pi (Works)
c * n (Error)
我查了一下:
>:t pi
pi :: Floating a => a
>:t n
n :: Double
问题在于类型,但我不知道如何获得 在它周围。
在这种情况下,我是否需要定义自己的(/)
函数?
更新 我从ghci获得的错误:
Couldn't match expected type `Vector Double'
with actual type `Double'
In the second argument of `(*)', namely `n'
In the expression: c * n
In an equation for `it': it = c * n
答案 0 :(得分:2)
通过检查类型,你做的是正确的。如果我们更明确一点,我们可以看到发生了什么。
Prelude Numeric.LinearAlgebra> :t let a = 2; b = c * a in a
let a = 2; b = c * a in a :: Vector Double
问题是norm2 c
的类型是Double
,因此无法制作成Vector Double
让我们看看之前的多态2
的价值。
Prelude Numeric.LinearAlgebra> let a = 2; b = c * a in a
fromList [2.0]
相反,n = fromList [norm2 c]
编辑:完全相同的库会公开您应该查看的函数scalar
和scale
。
答案 1 :(得分:2)
(*)
假设它的两个参数都具有相同的类型:
(*) :: (Num a) => a -> a -> a
你的前三次乘法运作的原因是因为在所有三种情况下,正确的参数成功地被检查为Vector Double
!
要了解原因,让我们问ghci
这三个论点的类型是什么:
> :t 2
2 :: Num a => a
> :t 0.5
0.5 :: Fractional a => a
> :t pi
pi :: Floating a => a
所有这三个都是有效的Vector Double
,因为hmatrix
提供了以下三个实例:
instance Num (Vector Double) where ...
instance Fractional (Vector Double) where ...
instance Floating (Vector Double) where ...
换句话说,由于这些情况,Haskell会自动将2
,0.5
和pi
转换为Vector Double
。
这解释了为什么你的上一个例子没有打字检查。 n
的类型为Double
,这意味着它也无法进行类型检查Vector Double
。