Struct 构造Poly/ML参数化结构值

Struct 构造Poly/ML参数化结构值,struct,types,functor,polyml,Struct,Types,Functor,Polyml,我想创建一个基于另一个可以切换实现的结构的结构 signature Field = sig type field_type; val zero : field_type; val add : (field_type * field_type) -> field_type; val f : int -> field_type; end; structure Reals :> Field = struct type field_type = real;

我想创建一个基于另一个可以切换实现的结构的结构

signature Field = 
sig
  type field_type;
  val zero : field_type;
  val add : (field_type * field_type) -> field_type;
  val f : int -> field_type;
end;

structure Reals :> Field = 
struct
  type field_type = real;
  val zero = 0.0;
  fun add (x,y) = x + y;
  fun f x = Real.fromInt(x);
end;

structure Rat :> Field = 
struct
   type field_type = int * int;
   val zero = (0, 1);
   fun add ((i1,i2),(j1,j2)) = (i1*j2 + j1*i2, i2*j2);
   fun f x = (x, 1);
end;

functor Useable(F : Field) = 
struct
   type field_type = F.field_type;
   val zero = F.zero;
   fun add(x,y) = F.add(x,y);
   fun f x = F.f x;
end;

structure ReF = Useable(Reals);
structure RaF = Useable(Rat);
我的想法是可以插入Field的实现(Reals或Rat,忽略低效的实现)

我可以运行此代码
ReF.add(ReF.zero,ReF,zero)
,但不能运行
ReF.add(0.0,0.0)
(或
RaF.add((0,1)、(0,1))


为了克服这个问题,我创建了一个构造函数
f:int->field\u types
,但我发现它并不优雅,也很麻烦。为了能够使用
ReF.add(0.0,0.0)
,我能做些什么吗?

简单的答案是使用透明签名约束

structure Reals : Field
而不是不透明的约束

structure Reals :> Field
当您使用不透明约束时,签名中的类型(如field_type)将被创建为不同于用于实现它们的类型的新类型。如果要保留到原始类型的链接,则需要使用透明约束。对于透明约束,Reals.field_类型和real是相同的类型,因此您可以使用

ReF.add(0.0, 0.0);
非常好

> ReF.add(0.0, 0.0);
val it = 0.0: real
作为使用透明约束的替代方法,如果签名中有其他类型希望创建为新类型,则仍然可以通过使用不透明约束和where类型来获得所需的效果

structure Reals :> Field where type field_type = real