0

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

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)吗?

4

1 回答 1

2

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

structure Reals : Field

而不是一个不透明的约束。

structure Reals :> Field

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

ReF.add(0.0, 0.0);

非常好。

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

作为使用透明约束的替代方法,如果您的签名中有其他类型要创建为新类型,您仍然可以通过使用不透明约束和where type来获得所需的效果。

structure Reals :> Field where type field_type = real
于 2013-10-25T08:04:22.897 回答