问题
Trying to use hmatrix, to create a zero marix. For some reason, when I try this on command line, it works:
buildMatrix 2 3 (\(r,c) -> fromIntegral 0)
However, when I try to do the same thing in my code:
type Dim = (Int, Int)
buildFull :: Matrix Double -> Vector Int -> Vector Int -> Dim -> Int
buildFull matrix basic nonbasic (m, n) = do
-- Build mxn matrix of zeroes
let f = buildMatrix m n (\(r,c) -> fromIntegral 0)
m
it fails:
Pivot.hs:23:17:
Ambiguous type variable `a0' in the constraints:
(Element a0) arising from a use of `buildMatrix'
at Pivot.hs:23:17-27
(Num a0) arising from a use of `fromIntegral' at Pivot.hs:23:44-55
Probable fix: add a type signature that fixes these type variable(s)
In the expression: buildMatrix m n (\ (r, c) -> fromIntegral 0)
In an equation for `f':
f = buildMatrix m n (\ (r, c) -> fromIntegral 0)
In the expression:
do { let f = buildMatrix m n (\ (r, c) -> ...);
m }
Failed, modules loaded: none.
回答1:
type Dim = (Int, Int)
buildFull :: Matrix Double -> Vector Int -> Vector Int -> Dim -> Int
buildFull matrix basic nonbasic (m, n) = do
-- Build mxn matrix of zeroes
let f = buildMatrix m n (\(r,c) -> fromIntegral 0)
m
First, to use do
-notation, you need a monadic return type, so that won't compile even after fixing the ambiguous element type (as I was reminded by @Carl, it would be okay here while there's only a single expression so that no (>>=)
or (>>)
is needed).
Concerning the element type, in the let-binding, there is no way to find out which type to use, whether fromIntegral
should return Double
, Integer
or whatever. Often the type to be used can be inferred from context, by the expressions it is used in. Here, f
is nowhere used, so there's no context. Hence in this situation, you have to specify the type by a signature, that can be
let f :: Matrix Double
f = buildMatrix m n (const 0)
or
let f = buildMatrix m n (\_ -> (0 :: Double))
if you want the element type o be Double
.
回答2:
You can also use konst
from Numeric.Container:
import Numeric.LinearAlgebra
m = konst 0 (2,3) :: Matrix Double
v = konst 7 10 :: Vector (Complex Float)
回答3:
Replace fromIntegral 0
with 0::Double
. Otherwise the sort of matrix you want to build is underconstrained. At the prompt, extended defaulting rules are probably solving that problem for you.
来源:https://stackoverflow.com/questions/8434808/how-to-build-matrix-of-zeros-using-hmatrix