diff: polymorphism.m: specialize typeclass method calls

Fergus Henderson fjh at cs.mu.OZ.AU
Tue Jan 27 23:31:24 AEDT 1998


Hi,

David, can you please review this one?

Estimated hours taken: 4 (plus 1 or 2 from dgj)

compiler/polymorphism.m:	
	For calls to class methods, if the particular class instance is
	known at the call site, then specialize the code by generating
	a direct call to the method for that instance.

tests/invalid/Mmakefile:
tests/invalid/typeclass_test_{1,2,3,4}.m:
tests/invalid/typeclass_test_{1,2,3,4}.exp:
tests/hard_coded/Mmakefile:
tests/hard_coded/typeclass_test_{5,6}.m:
tests/hard_coded/typeclass_test_{5,6}.exp:
	Some test cases for type classes, including one for the above change.

Index: polymorphism.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/polymorphism.m,v
retrieving revision 1.123
diff -u -u -r1.123 polymorphism.m
--- polymorphism.m	1998/01/23 12:11:58	1.123
+++ polymorphism.m	1998/01/27 12:14:14
@@ -581,15 +581,15 @@
 	->
 		{ classify_type(Type, ModuleInfo, TypeCategory) },
 		{ polymorphism__get_special_proc(TypeCategory, Type,
-			SpecialPredId, ModuleInfo, Name, PredId, ProcId) }
+			SpecialPredId, ModuleInfo, Name, PredId1, ProcId1) }
 	;
-		{ PredId = PredId0 },
-		{ ProcId = ProcId0 },
+		{ PredId1 = PredId0 },
+		{ ProcId1 = ProcId0 },
 		{ Name = Name0 }
 	),
 
-	polymorphism__process_call(PredId, ProcId, ArgVars0,
-		ArgVars, ExtraVars, ExtraGoals),
+	polymorphism__process_call(PredId1, ProcId1, ArgVars0,
+		PredId, ProcId, ArgVars, ExtraVars, ExtraGoals),
 	{ goal_info_get_nonlocals(GoalInfo, NonLocals0) },
 	{ set__insert_list(NonLocals0, ExtraVars, NonLocals) },
 	{ goal_info_set_nonlocals(GoalInfo, NonLocals, CallGoalInfo) },
@@ -744,11 +744,11 @@
 	polymorphism__process_goal(B0, B),
 	polymorphism__process_goal(C0, C).
 
-polymorphism__process_goal_expr(pragma_c_code(IsRecursive, PredId, ProcId,
+polymorphism__process_goal_expr(pragma_c_code(IsRecursive, PredId0, ProcId0,
 		ArgVars0, ArgInfo0, OrigArgTypes0, PragmaCode),
 		GoalInfo, Goal) -->
-	polymorphism__process_call(PredId, ProcId, ArgVars0,
-		ArgVars, ExtraVars, ExtraGoals),
+	polymorphism__process_call(PredId0, ProcId0, ArgVars0,
+		PredId, ProcId, ArgVars, ExtraVars, ExtraGoals),
 	%
 	% update the non-locals
 	%
@@ -831,17 +831,19 @@
 
 %-----------------------------------------------------------------------------%
 
-:- pred polymorphism__process_call(pred_id, proc_id, list(var), list(var),
+:- pred polymorphism__process_call(pred_id, proc_id, list(var),
+					pred_id, proc_id, list(var),
 					list(var), list(hlds_goal),
 					poly_info, poly_info).
-:- mode polymorphism__process_call(in, in, in, out, out, out, in, out) is det.
+:- mode polymorphism__process_call(in, in, in, out, out, out, out, out,
+					in, out) is det.
 
-polymorphism__process_call(PredId, _ProcId, ArgVars0, ArgVars,
+polymorphism__process_call(PredId0, ProcId0, ArgVars0, PredId, ProcId, ArgVars,
 				ExtraVars, ExtraGoals, Info0, Info) :-
 
 	Info0 = poly_info(A, VarTypes, TypeVarSet0, D, E, F, G, ModuleInfo),
 
-	module_info_pred_info(ModuleInfo, PredId, PredInfo),
+	module_info_pred_info(ModuleInfo, PredId0, PredInfo),
 	pred_info_arg_types(PredInfo, PredTypeVarSet, PredArgTypes0),
 	pred_info_get_class_context(PredInfo, PredClassContext0),
 		% rename apart
@@ -852,6 +854,8 @@
 	term__vars_list(PredArgTypes, PredTypeVars0),
 	( PredTypeVars0 = [] ->
 		% optimize for common case of non-polymorphic call
+		PredId = PredId0,
+		ProcId = ProcId0,
 		ArgVars = ArgVars0,
 		ExtraGoals = [],
 		ExtraVars = [],
@@ -876,9 +880,12 @@
 			% Make the typeclass_infos for the call, and return
 			% a list of which variables were constrained by the
 			% context
-		polymorphism__make_typeclass_info_vars(PredClassContext,
-			Subst, TypeSubst, ExtraTypeClassVars, 
-			ExtraTypeClassGoals, ConstrainedVars, Info1, Info2),
+		polymorphism__make_typeclass_info_vars(	
+			PredClassContext, Subst, TypeSubst,
+			hlds_class_proc(PredId0, ProcId0),
+			hlds_class_proc(PredId, ProcId),
+			ExtraTypeClassVars, ExtraTypeClassGoals,
+			ConstrainedVars, Info1, Info2),
 
 			% No need to make typeinfos for the constrained vars
 		list__delete_elems(PredTypeVars1, ConstrainedVars,
@@ -991,18 +998,24 @@
 
 %---------------------------------------------------------------------------%
 
-% Given a list of constraints, create a list of variables to hold the
-% typeclass_info for those constraints, and create a list of goals to 
-% initialize those typeclass_info variables to the appropriate 
-% typeclass_info structures for the constraints.
+% Given the list of constraints for a called predicate, create a list of
+% variables to hold the typeclass_info for those constraints,
+% and create a list of goals to initialize those typeclass_info variables
+% to the appropriate typeclass_info structures for the constraints.
+% If the called predicate is a class method, and we know which instance
+% it is, then instead of creating a type_info variable for the type class
+% instance, just return the pred_proc_id for that instance.
+% Otherwise return the original pred_proc_id unchanged.
 
 :- pred polymorphism__make_typeclass_info_vars(list(class_constraint),
-	substitution, tsubst, list(var), list(hlds_goal), list(var),
+	substitution, tsubst, hlds_class_proc, hlds_class_proc,
+	list(var), list(hlds_goal), list(var),
 	poly_info, poly_info).
-:- mode polymorphism__make_typeclass_info_vars(in, in, in, out, out, out, 
-	in, out) is det.
+:- mode polymorphism__make_typeclass_info_vars(in, in, in, in, out,
+	out, out, out, in, out) is det.
 
 polymorphism__make_typeclass_info_vars(PredClassContext, Subst, TypeSubst, 
+		PredProcId0, PredProcId,
 		ExtraVars, ExtraGoals, ConstrainedVars, Info0, Info) :-
 
 		% initialise the accumulators
@@ -1010,9 +1023,16 @@
 	ExtraGoals0 = [],
 	ConstrainedVars0 = [],
 
+		% The PredProcId is set to `yes(_)' for the first call only,
+		% because we can only specialize method calls if we know the
+		% which instance of the method's type class it is; knowing
+		% the instances for any of the other type class constraints
+		% on a method doesn't help us specialize the call.
+	MaybePredProcId0 = yes(PredProcId0),
+
 		% do the work
 	polymorphism__make_typeclass_info_vars_2(PredClassContext, 
-		Subst, TypeSubst, 
+		Subst, TypeSubst, MaybePredProcId0, MaybePredProcId,
 		ExtraVars0, ExtraVars1, 
 		ExtraGoals0, ExtraGoals1,
 		ConstrainedVars0, ConstrainedVars, 
@@ -1020,51 +1040,66 @@
 	
 		% We build up the vars and goals in reverse order
 	list__reverse(ExtraVars1, ExtraVars),
-	list__reverse(ExtraGoals1, ExtraGoals).
+	list__reverse(ExtraGoals1, ExtraGoals),
+
+		% If we succeeded in specializing this call, then use
+		% the specialization, otherwise use the original call.
+	( MaybePredProcId = yes(PredProcId1) ->
+		PredProcId = PredProcId1
+	;
+		PredProcId = PredProcId0
+	).
 
 % Accumulator version of the above.
-:- pred polymorphism__make_typeclass_info_vars_2(list(class_constraint),
-	substitution, tsubst, 
+:- pred polymorphism__make_typeclass_info_vars_2(
+	list(class_constraint), substitution, tsubst,
+	maybe(hlds_class_proc), maybe(hlds_class_proc),
 	list(var), list(var), 
 	list(hlds_goal), list(hlds_goal), 
 	list(var), list(var),
 	poly_info, poly_info).
-:- mode polymorphism__make_typeclass_info_vars_2(in, in, in, in, out, in, out,
-	in, out, in, out) is det.
+:- mode polymorphism__make_typeclass_info_vars_2(in, in, in,
+	in, out, in, out, in, out, in, out, in, out) is det.
 
 polymorphism__make_typeclass_info_vars_2([], _Subst, _TypeSubst,
+		MaybePredProcId, MaybePredProcId,
 		ExtraVars, ExtraVars, 
 		ExtraGoals, ExtraGoals, 
 		ConstrainedVars, ConstrainedVars,
 		Info, Info).
 polymorphism__make_typeclass_info_vars_2([C|Cs], Subst, TypeSubst,
-		ExtraVars0, ExtraVars, 
+		MaybePredProcId0, MaybePredProcId,
+		ExtraVars0, ExtraVars,
 		ExtraGoals0, ExtraGoals, 
 		ConstrainedVars0, ConstrainedVars,
 		Info0, Info) :-
 	polymorphism__make_typeclass_info_var(C, Subst, TypeSubst,
+			MaybePredProcId0, MaybePredProcId,
 			ExtraGoals0, ExtraGoals1, 
-			ConstrainedVars0, ConstrainedVars1, Info0, Info1,
-			ExtraVar),
+			ConstrainedVars0, ConstrainedVars1,
+			Info0, Info1, MaybeExtraVar),
+	maybe_insert_var(MaybeExtraVar, ExtraVars0, ExtraVars1),
 	polymorphism__make_typeclass_info_vars_2(Cs, Subst, TypeSubst,
-			[ExtraVar|ExtraVars0], ExtraVars, 
+			no, _,
+			ExtraVars1, ExtraVars,
 			ExtraGoals1, ExtraGoals, 
 			ConstrainedVars1, ConstrainedVars,
 			Info1, Info).
 
 :- pred polymorphism__make_typeclass_info_var(class_constraint,
-	substitution, tsubst,
+	substitution, tsubst, maybe(hlds_class_proc), maybe(hlds_class_proc),
 	list(hlds_goal), list(hlds_goal), 
 	list(var), list(var),
 	poly_info, poly_info,
-	var). 
-:- mode polymorphism__make_typeclass_info_var(in, in, in, in, out, in, out, 
-	in, out, out) is det.
+	maybe(var)). 
+:- mode polymorphism__make_typeclass_info_var(in, in, in, in, out,
+	in, out, in, out, in, out, out) is det.
 
 polymorphism__make_typeclass_info_var(Constraint, Subst, TypeSubst,
+		MaybePredProcId0, MaybePredProcId,
 		ExtraGoals0, ExtraGoals, 
 		ConstrainedVars0, ConstrainedVars, 
-		Info0, Info, Var) :-
+		Info0, Info, MaybeVar) :-
 	Constraint = constraint(ClassName, NewConstrainedTypes),
 	list__length(NewConstrainedTypes, ClassArity),
 	ClassId = class_id(ClassName, ClassArity),
@@ -1083,6 +1118,8 @@
 			% We already have a typeclass_info for this constraint
 		ExtraGoals = ExtraGoals0,
 		Var = Location,
+		MaybeVar = yes(Var),
+		MaybePredProcId = no,
 		Info = Info0
 	;
 			% We don't have the typeclass_info as a parameter to
@@ -1094,42 +1131,113 @@
 		(
 				% We have to construct the typeclass_info
 				% using an instance declaration
-			Proof = apply_instance(InstanceDefn, InstanceNum),
+			Proof = apply_instance(ProofInstanceDefn, InstanceNum),
 
 				% The subst has already been applied to these
 				% constraints in typecheck.m
-			InstanceDefn = hlds_instance_defn(_,
+			ProofInstanceDefn = hlds_instance_defn(_,
 				InstanceConstraints, _, _, _, _, _),
 
-				% Make the type_infos for the types that are
-				% constrained by this. These are packaged in
-				% the typeclass_info
-			polymorphism__make_type_info_vars(ConstrainedTypes,
-				InstanceExtraTypeInfoVars, TypeInfoGoals, 
-				Info0, Info1),
-
-				% Make the typeclass_infos for the constraints
-				% from the context of the instance decl.
-			polymorphism__make_typeclass_info_vars_2(
-				InstanceConstraints,
-				Subst, TypeSubst, 
-				[], InstanceExtraTypeClassInfoVars, 
-				ExtraGoals0, ExtraGoals1, 
-				[], _, Info1, Info2),
+			%
+			% Check whether the callee is a class method,
+			% and that this contraint is the first constraint
+			% in that callee's constraint list (the one for
+			% its own type class).
+			% If so, specialize the call by replacing the
+			% generic class method call with a direct call
+			% to the class method for this instance.
+			%
+			(
+				% check that this constraint is the
+				% first constraint in the callee's
+				% constraint list
+				MaybePredProcId0 = yes(PredProcId0),
+
+				% check that the called pred is a class method
+				PredProcId0 = hlds_class_proc(PredId0, _),
+				module_info_pred_info(ModuleInfo, PredId0,
+						PredInfo),
+				pred_info_get_markers(PredInfo, Markers),
+				check_marker(Markers, class_method)
+			->
+				% Get the class methods, and figure out
+				% the method number of this class method.
+				module_info_classes(ModuleInfo, ClassTable),
+				map__lookup(ClassTable, ClassId, ClassDefn),
+				ClassDefn = hlds_class_defn(_, _, ClassMethods,
+						_, _),
+				( list__nth_member_search(ClassMethods,
+						PredProcId0, MethodNum0) ->
+					MethodNum = MethodNum0
+				;
+					error("poly: nth_member_search failed")
+				),
 
-			polymorphism__construct_typeclass_info(
-				InstanceExtraTypeInfoVars, 
-				InstanceExtraTypeClassInfoVars, 
-				ClassId, InstanceNum, Var, NewGoals, 
-				Info2, Info),
-
-				% Oh, yuck. The type_info goals have already
-				% been reversed, so lets reverse them back.
-			list__reverse(TypeInfoGoals, RevTypeInfoGoals),
-
-			list__append(ExtraGoals1, RevTypeInfoGoals,
-				ExtraGoals2),
-			list__append(NewGoals, ExtraGoals2, ExtraGoals)
+				% Get the instance methods, and lookup
+				% the pred for the corresponding method number.
+				% (NB. We can't use ProofInstanceDefn,
+				% because its MaybeInstanceMethods field
+				% has not been updated (is still `no').)
+				module_info_instances(ModuleInfo,
+					InstanceTable),
+				map__lookup(InstanceTable, ClassId,
+					InstanceDefns),
+				list__index1_det(InstanceDefns, InstanceNum,
+					InstanceDefn),
+				InstanceDefn = hlds_instance_defn(_, _, _, _,
+					MaybeInstanceMethods, _, _),
+				( MaybeInstanceMethods = yes(InstanceMethods0)
+				->
+					InstanceMethods = InstanceMethods0
+				;
+					error("poly: no instance methods")
+				),
+				list__index1_det(InstanceMethods, MethodNum,
+					InstanceMethod),
+				MaybePredProcId = yes(InstanceMethod),
+				MaybeVar = no,
+				ExtraGoals = ExtraGoals0,
+				Info = Info0
+			;
+
+					% Make the type_infos for the types
+					% that are constrained by this. These
+					% are packaged in the typeclass_info
+				polymorphism__make_type_info_vars(
+					ConstrainedTypes,
+					InstanceExtraTypeInfoVars,
+					TypeInfoGoals,
+					Info0, Info1),
+
+					% Make the typeclass_infos for the
+					% constraints from the context of the
+					% instance decl.
+				polymorphism__make_typeclass_info_vars_2(
+					InstanceConstraints, Subst, TypeSubst, 
+					no, _,
+					[], InstanceExtraTypeClassInfoVars, 
+					ExtraGoals0, ExtraGoals1, 
+					[], _,
+					Info1, Info2),
+
+				polymorphism__construct_typeclass_info(
+					InstanceExtraTypeInfoVars, 
+					InstanceExtraTypeClassInfoVars, 
+					ClassId, InstanceNum, Var, NewGoals, 
+					Info2, Info),
+
+				MaybeVar = yes(Var),
+				MaybePredProcId = no,
+
+					% Oh, yuck. The type_info goals have
+					% already been reversed, so lets
+					% reverse them back.
+				list__reverse(TypeInfoGoals, RevTypeInfoGoals),
+
+				list__append(ExtraGoals1, RevTypeInfoGoals,
+					ExtraGoals2),
+				list__append(NewGoals, ExtraGoals2, ExtraGoals)
+			)
 		;
 				% We have to extract the typeclass_info from
 				% another one
@@ -1141,6 +1249,9 @@
 			polymorphism__new_typeclass_info_var(VarSet0, VarTypes0,
 				ClassNameString, Var, VarSet1, VarTypes1),
 
+			MaybeVar = yes(Var),
+			MaybePredProcId = no,
+
 				% Then work out where to extract it from
 			SubClassConstraint0 = 
 				constraint(SubClassName, SubClassTypes0),
@@ -1157,12 +1268,17 @@
 
 				% Make the typeclass_info for the subclass
 			polymorphism__make_typeclass_info_var(
-				SubClassConstraint,
-				Subst, TypeSubst, 
+				SubClassConstraint, Subst, TypeSubst, 
+				no, _,
 				ExtraGoals0, ExtraGoals1, 
 				[], _,
 				Info1, Info2,
-				SubClassVar), 
+				MaybeSubClassVar), 
+			( MaybeSubClassVar = yes(SubClassVar0) ->
+				SubClassVar = SubClassVar0
+			;
+				error("MaybeSubClassVar = no")
+			),
 
 				% Look up the definition of the subclass
 			module_info_classes(ModuleInfo, ClassTable),
@@ -1404,11 +1520,17 @@
 polymorphism__make_superclasses_from_proofs([], _, _, 
 		Goals, Goals, Info, Info, Vars, Vars).
 polymorphism__make_superclasses_from_proofs([C|Cs], Subst, TypeSubst, 
-		Goals0, Goals, Info0, Info, Vars0, [Var|Vars]) :-
+		Goals0, Goals, Info0, Info, Vars0, Vars) :-
 	polymorphism__make_superclasses_from_proofs(Cs, Subst, TypeSubst,
-		Goals0, Goals1, Info0, Info1, Vars0, Vars),
+		Goals0, Goals1, Info0, Info1, Vars0, Vars1),
 	polymorphism__make_typeclass_info_var(C, Subst, TypeSubst,
-		Goals1, Goals, [], _, Info1, Info, Var).
+		no, _, Goals1, Goals, [], _, Info1, Info, MaybeVar),
+	maybe_insert_var(MaybeVar, Vars1, Vars).
+
+:- pred maybe_insert_var(maybe(var), list(var), list(var)).
+:- mode maybe_insert_var(in, in, out) is det.
+maybe_insert_var(no, Vars, Vars).
+maybe_insert_var(yes(Var), Vars, [Var | Vars]).
 
 %---------------------------------------------------------------------------%
 
cvs diff: Diffing .
Index: Mmakefile
===================================================================
RCS file: /home/mercury1/repository/tests/hard_coded/Mmakefile,v
retrieving revision 1.10
diff -u -u -r1.10 Mmakefile
--- Mmakefile	1998/01/22 07:12:28	1.10
+++ Mmakefile	1998/01/27 11:51:55
@@ -61,8 +61,12 @@
 	string_loop \
 	test_imported_no_tag \
 	tim_qual1 \
+	typeclass_test_6 \
 	write \
 	write_reg1
+
+# we do not yet pass the following tests:
+#	typeclass_test_5.m (this is really a WISHLIST item)
 
 #-----------------------------------------------------------------------------#
 
Index: typeclass_test_5.exp
===================================================================
RCS file: typeclass_test_5.exp
diff -N typeclass_test_5.exp
--- /dev/null	Tue Jan 27 23:11:08 1998
+++ typeclass_test_5.exp	Tue Jan 27 22:53:09 1998
@@ -0,0 +1 @@
+42
Index: typeclass_test_5.m
===================================================================
RCS file: typeclass_test_5.m
diff -N typeclass_test_5.m
--- /dev/null	Tue Jan 27 23:11:08 1998
+++ typeclass_test_5.m	Tue Jan 27 22:52:11 1998
@@ -0,0 +1,20 @@
+:- module foo4.
+:- interface.
+:- import_module io.
+:- pred main(io__state::di, io__state::uo) is det.
+
+:- implementation.
+
+main --> io__write_int(type_num(43)), io__nl.
+
+:- typeclass numbered_type(T) where [
+	func type_num(T::in) = (int::out) is det
+].
+
+:- instance numbered_type(int) where [
+	func(type_num/1) is foo_type_num
+].
+
+:- func foo_type_num(T::in) = (int::out) is det.
+foo_type_num(_) = 42.
+
Index: typeclass_test_6.exp
===================================================================
RCS file: typeclass_test_6.exp
diff -N typeclass_test_6.exp
--- /dev/null	Tue Jan 27 23:11:08 1998
+++ typeclass_test_6.exp	Tue Jan 27 22:53:11 1998
@@ -0,0 +1 @@
+42
Index: typeclass_test_6.m
===================================================================
RCS file: typeclass_test_6.m
diff -N typeclass_test_6.m
--- /dev/null	Tue Jan 27 23:11:08 1998
+++ typeclass_test_6.m	Tue Jan 27 22:52:15 1998
@@ -0,0 +1,20 @@
+:- module foo4.
+:- interface.
+:- import_module io.
+:- pred main(io__state::di, io__state::uo) is det.
+
+:- implementation.
+
+main --> io__write_int(type_num(43)), io__nl.
+
+:- typeclass numbered_type(T) where [
+	func type_num(T::in) = (int::out) is det
+].
+
+:- instance numbered_type(int) where [
+	func(type_num/1) is foo_type_num
+].
+
+:- func foo_type_num(int::in) = (int::out) is det.
+foo_type_num(_) = 42.
+
cvs diff: Diffing .
Index: Mmakefile
===================================================================
RCS file: /home/mercury1/repository/tests/invalid/Mmakefile,v
retrieving revision 1.9
diff -u -u -r1.9 Mmakefile
--- Mmakefile	1998/01/12 13:30:00	1.9
+++ Mmakefile	1998/01/27 11:51:15
@@ -37,6 +37,9 @@
 	qualified_cons_id2.m \
 	type_loop.m \
 	type_mismatch.m \
+	typeclass_test_1.m \
+	typeclass_test_2.m \
+	typeclass_test_4.m \
 	unbound_inst_var.m \
 	undef_lambda_mode.m \
 	undef_mode.m \
@@ -45,8 +48,12 @@
 	vars_in_wrong_places.m
 
 # we do not yet pass the following tests:
+#	typeclass_test_3.m (gets software error; cause unknown)
 #	freefree.m 	(need bromage's aliasing stuff)
 #	no_exports.m	(this is really a WISHLIST item)
+#
+# we do a very bad job on the following tests:
+#	typeclass_test_4.m (awful error message)
 
 MCFLAGS-multisoln_func	=	--infer-types
 MCFLAGS-any_mode	=	--infer-types
Index: typeclass_test_1.err_exp
===================================================================
RCS file: typeclass_test_1.err_exp
diff -N typeclass_test_1.err_exp
--- /dev/null	Tue Jan 27 23:11:08 1998
+++ typeclass_test_1.err_exp	Tue Jan 27 22:41:58 1998
@@ -0,0 +1,7 @@
+test_typeclass_1.m:001: Warning: module should start with a `:- module' declaration.
+test_typeclass_1.m:014: Error: expected `pred(<Name> / <Arity>) is <InstanceName>': type_num is foo_type_num.
+test_typeclass_1.m:017: Syntax error at variable `_': operator or `.' expected.
+test_typeclass_1.m:007: In clause for predicate `test_typeclass_1:main/2':
+test_typeclass_1.m:007:   unsatisfied typeclass constraint(s):
+test_typeclass_1.m:007:   test_typeclass_1:numbered_type(int)
+For more information, try recompiling with `-E'.
Index: typeclass_test_1.m
===================================================================
RCS file: typeclass_test_1.m
diff -N typeclass_test_1.m
--- /dev/null	Tue Jan 27 23:11:08 1998
+++ typeclass_test_1.m	Tue Jan 27 22:39:37 1998
@@ -0,0 +1,18 @@
+:- interface.
+:- import_module io.
+:- pred main(io__state::di, io__state::uo) is det.
+
+:- implementation.
+
+main --> io__write_int(type_num(42)).
+
+:- typeclass numbered_type(T) where [
+	func type_num(T) = int
+].
+
+:- instance foo(int) where [
+	type_num is foo_type_num
+].
+
+foo_type_num _ = 42.
+
Index: typeclass_test_2.err_exp
===================================================================
RCS file: typeclass_test_2.err_exp
diff -N typeclass_test_2.err_exp
--- /dev/null	Tue Jan 27 23:11:08 1998
+++ typeclass_test_2.err_exp	Tue Jan 27 22:42:43 1998
@@ -0,0 +1,9 @@
+test_typeclass_2.m:001: Warning: incorrect module name in `:- module' declaration.
+test_typeclass_2.m:015: Error: expected `pred(<Name> / <Arity>) is <InstanceName>': type_num / 0 is foo_type_num.
+test_typeclass_2.m:018: Error: clause for function `test_typeclass_2:foo_type_num/1'
+test_typeclass_2.m:018:   without preceding `func' declaration.
+test_typeclass_2.m:008: In clause for predicate `test_typeclass_2:main/2':
+test_typeclass_2.m:008:   unsatisfied typeclass constraint(s):
+test_typeclass_2.m:008:   test_typeclass_2:numbered_type(int)
+test_typeclass_2.m:018: Inferred :- func foo_type_num(T1) = int.
+For more information, try recompiling with `-E'.
Index: typeclass_test_2.m
===================================================================
RCS file: typeclass_test_2.m
diff -N typeclass_test_2.m
--- /dev/null	Tue Jan 27 23:11:08 1998
+++ typeclass_test_2.m	Tue Jan 27 22:41:00 1998
@@ -0,0 +1,19 @@
+:- module foo.
+:- interface.
+:- import_module io.
+:- pred main(io__state::di, io__state::uo) is det.
+
+:- implementation.
+
+main --> io__write_int(type_num(42)).
+
+:- typeclass numbered_type(T) where [
+	func type_num(T) = int
+].
+
+:- instance numbered_type(int) where [
+	type_num/0 is foo_type_num
+].
+
+foo_type_num(_) = 42.
+
Index: typeclass_test_3.err_exp
===================================================================
RCS file: typeclass_test_3.err_exp
diff -N typeclass_test_3.err_exp
--- /dev/null	Tue Jan 27 23:11:08 1998
+++ typeclass_test_3.err_exp	Tue Jan 27 23:27:13 1998
@@ -0,0 +1,2 @@
+test_typeclass_3.m:001: Warning: incorrect module name in `:- module' declaration.
+XXX
Index: typeclass_test_3.m
===================================================================
RCS file: typeclass_test_3.m
diff -N typeclass_test_3.m
--- /dev/null	Tue Jan 27 23:11:08 1998
+++ typeclass_test_3.m	Tue Jan 27 21:22:25 1998
@@ -0,0 +1,20 @@
+:- module foo3.
+:- interface.
+:- import_module io.
+:- pred main(io__state::di, io__state::uo) is det.
+
+:- implementation.
+
+main --> io__write_int(type_num(42)).
+
+:- typeclass numbered_type(T) where [
+	func type_num(T) = int
+].
+
+:- instance numbered_type(int) where [
+	func(type_num/0) is foo_type_num
+].
+
+:- func foo_type_num(T) = int.
+foo_type_num(_) = 42.
+
Index: typeclass_test_4.err_exp
===================================================================
RCS file: typeclass_test_4.err_exp
diff -N typeclass_test_4.err_exp
--- /dev/null	Tue Jan 27 23:11:08 1998
+++ typeclass_test_4.err_exp	Tue Jan 27 22:46:16 1998
@@ -0,0 +1,2 @@
+undefined class method
+For more information, try recompiling with `-E'.
Index: typeclass_test_4.m
===================================================================
RCS file: typeclass_test_4.m
diff -N typeclass_test_4.m
--- /dev/null	Tue Jan 27 23:11:08 1998
+++ typeclass_test_4.m	Tue Jan 27 22:46:04 1998
@@ -0,0 +1,20 @@
+:- module typeclass_test_4.
+:- interface.
+:- import_module io.
+:- pred main(io__state::di, io__state::uo) is det.
+
+:- implementation.
+
+main --> io__write_int(type_num(43)).
+
+:- typeclass numbered_type(T) where [
+	func type_num(T::in) = (int::out) is det
+].
+
+:- instance numbered_type(int) where [
+	func(type_num/0) is foo_type_num
+].
+
+:- func foo_type_num(T::in) = (int::out) is det.
+foo_type_num(_) = 42.
+
-- 
Fergus Henderson <fjh at cs.mu.oz.au>   |  "I have always known that the pursuit
WWW: <http://www.cs.mu.oz.au/~fjh>   |  of excellence is a lethal habit"
PGP: finger fjh at 128.250.37.3         |     -- the last words of T. S. Garp.



More information about the developers mailing list