
On Dec 26, 2007 10:28 PM, Steve Lihn
arising from use of `/' at DSLTest.hs:11:14-28
Thanks for the example. I am particularly amazed GHC is complaining at '/', not '+'. The type mismatch occurs (is reported) at much lower level. It would be nice if there is a way to bump it up a couple levels...
I suppose that is how the type inferencer works. To start with all it really "knows" is the types of 'phi' and 'mu'. Since it knows the type of 'mu' it can assume that 'v_GEO' has the same type, and from the definition of 'v_GEO' (and 'phi') it can infer a type for 'r_GEO'. But when checking that assumption against the definition of 'r_GEO' which depends on only 'phi' and 'mu' it realizes that things are amiss. (I'm just guessing here, the order, or way, in which the compiler does stuff may be totally different.) To be fair to the compiler it really has no way of knowing which definition is wrong without explicit type signatures. As I noted in my previous reply adding type signatures to all definitions allows the compiler to locate the error: In the second argument of `(+)', namely `mu' In the expression: v_GEO + mu I added this as an example to the library wiki[1]. The version of the code with type signatures is there and the whole page can be copy-pasted as literate haskell if you want to try it: [1] http://code.google.com/p/dimensional/wiki/ErrorMessagesAndDebugging
On Dec 26, 2007 12:56 PM, Bjorn Buckwalter
wrote: Steve Lihn
writes: I do come aross a question while reading the DSL page on Wikipedia.
http://en.wikipedia.org/wiki/Domain-specific_programming_language
In the Disadvantage section (near the end), there is an item -- hard or impossible to debug. Can anybody explain why or what it means? And how does it apply to Haskell?
I think I can give a good example of how this can apply to EMBEDDED DSLs. My library Dimensional (http://dimensional.googlecode.com) defines what someone referred to as a EDSL for working with physical units. The library leverages the Haskell type checker to provide static checking of physical dimensions. Without doing this I don't know how I could make such checking static.
The downside of this is that while you will be informed at compile time if you physical calculations are incorrect the error message itself is rarely useful. Here is an example with lines numbered:
1 import Numeric.Units.Dimensional.Prelude 2 import qualified Prelude 3 4 -- The angular velocity of Earth's rotation (Soop p. 7). 5 phi = 360.985647 *~ (degree / day) 6 7 -- The gravitational parameter of Earth. 8 mu = 3.986004400008003e14 *~ (meter ^ pos3 / second ^ pos2) 9 10 -- The ideal geostationary radius and velocity. 11 r_GEO = cbrt (mu / phi ^ pos2) 12 v_GEO = phi * r_GEO 13 14 -- Something obviously wrong. 15 dont_try_this_at_home = v_GEO + mu
Obviously we shouldn't be adding a velocity to a gravitational parameter on line 15 and the compiler will catch this. However, this is the error message from GHCi (6.6.1):
DSLTest.hs:1:0: Couldn't match expected type `Numeric.NumType.Neg n' against inferred type `Numeric.NumType.Zero' When using functional dependencies to combine Numeric.NumType.Sub a Numeric.NumType.Zero a, arising from the instance declaration at Defined in Numeric.NumType Numeric.NumType.Sub Numeric.NumType.Zero Numeric.NumType.Zero (Numeric.NumType.Neg n), arising from use of `/' at DSLTest.hs:11:14-28
I think you will agree that this isn't very helpful in pin-pointing the problem. The compiler is pointing at the definition of 'r_GEO' which is twice removed from the actual offender. Stuff like this can make EDSLs difficult to debug.
(In this particular example adding type signatures to all definitions will allow the compiler to pin-point the error to line 15, although the error message remains cryptic.)
Hope that helps, Bjorn
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe