I'm trying to understand the implementation of typeclasses in Curry so that I can implement them in my compiler. Is there some documentation describing how dictionaries are implemented, including the naming conventions used?
One problem I face is knowing how to choose default instances. For example, the program "main = 1 + 1" translates to the following FlatCurry:
program "test"
import "Prelude"
function "test.main" 1
lhs_vars [1]
Node "Prelude.apply" (
Node "Prelude.apply" (
Node "Prelude.+" (
var 1 ) ,
Node "Prelude.apply" (
Node "Prelude.fromInt" (
var 1 ) ,
int 1 ) ) ,
Node "Prelude.apply" (
Node "Prelude.fromInt" (
var 1 ) ,
int 1 ) )
Function "main" expects an implicit argument that is an instance of Prelude.Num. This is because no type declaration was specified, so its type is "Num a => a". If I were to declare main as having a concrete type such as Int or Float, then it would take no arguments.
KiCS2 and PAKCS can run this program, so they must somehow choose a default instance. How is this done?
I'm especially bothered that the FlatCurry appears to be missing crucial information - i.e., the fact that "main" expects a Num instance is not mentioned in the FlatCurry. How do other Curry implementations know to pass a Num dictionary and how is the default instance chosen?
-Andy
I can define an empty data type in Curry, e.g.:
data A
The built-in types such as Char, Int and Float are defined this way in the Prelude. Prior to the introduction of typeclasses the Curry frontend would translate this to a FlatCurry Type with no constructors. Newer versions produce a type with one constructor named "_Constr#A".
I'd like to understand how to interpret this. Is the above legal Curry? Is this perhaps a forward declaration or opaque type? Can the type, A, be defined later? If so, would it have to be defined in the same module? Is this documented somewhere?
I'm tempted to reject such a declaration unless the system can find a built-in definition but I don't want to reject legal programs.
-Andy