2017-07-04 4 views
1

標準MLにセットを実装しています。現在、それは次のようになります。SML異なる構造の共通タイプ

signature SET = sig 
    type t 
    type 'a set 
    ... 
    val map : ('a -> t) -> 'a set -> t set 
end 

functor ListSetFn (EQ : sig type t val equal : t * t -> bool end) 
     :> SET where type t = EQ.t = struct 
    type t = EQ.t 
    type 'a set = 'a list 
    ... 
    fun map f = fromList o (List.map f) 
end 

私は理想的にもListSetFnファンクタからのものに制約されない、map関数は構造SET内の任意のセットを取ることができるようにしたいです。しかし、それだけで単一の構造によって作成されたセット上で動作することができ、トップレベルの:それはから呼び出された1つ、例えば:

functor EqListSetFn(eqtype t) :> SET where type t = t = struct 
    structure T = ListSetFn(struct type t = t val equal = op= end) 
    open T 
end 

structure IntSet = EqListSetFn(type t = int) 
IntSet.map : ('a -> IntSet.t) -> 'a IntSet.set -> IntSet.t IntSet.set 

私は本当にそれがされるようにしたいようものの

IntSet.map : ('a -> IntSet.t) -> 'a ArbitrarySet.set -> IntSet.t IntSet.set 
のようなもの

これを行う方法はありますか?そのようなパラメータ化を実行するには2つの方法がありますが、私はそれがトップレベルで宣言することができ知っているが、私は内部の実装を隠し、したがって、原則的には不透明な署名(S)

答えて

2

を使用したい:

  1. 関数を独自のファンクタにラップします。ファンクタは、他の構造体を引数として取ります。

  2. 関連する関数を個別の引数として、または引数のレコードとして、他の型で操作するように関数を多態的にします。

のはSET署名は、これらの機能が含まれていると仮定しましょう:

val empty : 'a set 
val isEmpty : 'a set -> bool 
val add : 'a * 'a set -> 'a set 
val remove : 'a * 'a set -> 'a set 
val pick : 'a set -> 'a 

その後、旧ソリューションは次のようになります。解決策2については

functor SetMap (structure S1 : SET; structure S2 : SET) = 
struct 
    fun map f s = 
    if S1.isEmpty s then S2.empty else 
    let val x = S1.pick s 
    in S2.add (f x, map f (S2.remove (x, s))) 
    end 
end 

を、あなたはすべての関連を渡す必要があります直接関数、例えばレコードとして:

fun map {isEmpty, pick, remove} {empty, add} f s = 
    let 
     fun iter s = 
     if isEmpty s then empty else 
     let val x = pick s 
     in add (f x, iter (remove (x, s))) 
     end 
    in iter s end 

FWIW、これはファーストクラスの構造のよりよいだろうが、SMLは、標準機能として、それらを持っていません。

fun map (pack S1 : SET) (pack S2 : SET) f s = 
    let 
     fun iter s = 
     if S1.isEmpty s then S2.empty else 
     let val x = S1.pick s 
     in S2.add (f x, iter (S2.remove (x, s))) 
     end 
    in iter s end 
関連する問題