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)



Reply via email to