构造Poly / ML参数结构值

时间:2013-10-24 21:46:07

标签: 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;
  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_types,但我发现这不是那么优雅而且也很麻烦。我可以做任何事情来使用ReF.add(0.0, 0.0)吗?

1 个答案:

答案 0 :(得分:2)

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

structure Reals : Field

而不是不透明的约束。

structure Reals :> Field

当您使用不透明约束时,签名中的 field_type 类型会被创建为与用于实现它们的类型不同的新类型。如果要保留指向原始类型的链接,则需要使用透明约束。使用透明约束 Reals.field_type real 是相同的类型,因此您可以使用

ReF.add(0.0, 0.0);

非常好。

> ReF.add(0.0, 0.0);
val it = 0.0: real

作为使用透明约束的替代方法,如果您希望将签名中的其他类型创建为新类型,则仍可通过使用不透明约束以及类型<来获得所需效果/ em>的

structure Reals :> Field where type field_type = real