Hi everyone. I am a sometime O'Camler just learning Haskell. Type
classes are fun and I like the expressiveness you get without grafting a
whole "object system" onto your nice functional language. But sometimes
they baffle me, as in the following.
This function fails to typecheck:
-- Determinant algorithm from Knuth 4.6.4(31).
-- briefly: [x22 - (x21/x11)x12 ... x2n - (x21/x11)x1n]
-- det x[ij] = x11 det [ ... xij - (xi1/x11)x1j ... ]
-- [xn2 - (xn1/x11)x12 ... xnn - (xn1/x11)x1n]
det :: (Ix a, Num b) => Array (a,a) b -> b
det x | (i0,i1) /= (j0,j1) = error "det: square matrices only"
| null (range (i0,i1)) = (fromInteger 1)::b -- ERROR is here
| i0 == i1 = x!(i0,i0)
| True = x!(i0,i0) * det x'
where ((i0,j0), (i1,j1)) = bounds x
i'0 = (range (i0,i1)) !! 1
b' = ((i'0,i1), (i'0,i1))
x' = accum (-)
(array b' [(ij, x!ij) | ij <- range b'])
[((i,j), (x!(i,i0) / x!(i0,i0)) * x!(i0,j))
| (i,j) <- range b']
Hugs98 (May, Hugs extended mode) gives the error
ERROR "Matrix.hs" (line ...): Cannot justify constraints in type
annotation
*** Expression : fromInteger 1
*** Type : b
*** Given context : ()
*** Constraints : Num b
I wrote the offending clause as (fromInteger 1)::b because, when it was
just (fromInteger 1), the inferred type of det had b bound equal to Num
Double, which wasn't general enough to match my declared type. But as the
constraint Num b is declared in the type I want det to have, I don't
understand why the constraint is not found during type checking.
Simpler functions such as
test :: Num a => Bool -> a
test False = (fromInteger 0)::a
test True = (fromInteger 1)::a
typecheck just fine.
Can you show me what I am missing?
thanks & peace,
Chris Jeris (tries and fails to convince bosses to use functional langs)