我想创建一个基于另一个可以切换实现的结构的结构。
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)
吗?
答案 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