私はこれがSMLのファンクタで解決できる問題だと思います。
たとえば、質問(あなたの意味よりも低い)であなたの機能を定義するTOTALORDERという署名が存在するとします。
signature TOTALORDER =
sig
type element
val lt: element * element -> bool
end
あなたは関数がelement * element -> bool
として定義され、要素の型が、ここで定義されていない見ることができるように。
次のように私たちは、その後、さまざまなタイプで動作するようにTOTALORDERの二つの異なる実装を定義することができます。私たちの上
structure String : TOTALORDER =
struct
type element = string
fun lt(a:string, b) = a < b
end
structure Integer: TOTALORDER =
struct
type element = int
fun lt(a, b) = a < b
end
は作業列の可能な実装、および整数を扱うことのできる別のものを定義しています。これらの実装では、実際のタイプがelement
であることを定義していることがわかります。
次のように今、私たちは、関手に交換可能なタイプの魔法を定義することができます。
functor MakeComparator(Lt: TOTALORDER):
sig
val descending : Lt.element * Lt.element -> Lt.element * Lt.element
val ascending : Lt.element * Lt.element -> Lt.element * Lt.element
end
=
struct
open Lt;
fun descending(a,b) = if lt(a,b) then (b,a) else (a,b)
fun ascending(a,b) = if lt(a,b) then (a,b) else (b,a)
end
そしてここで我々はファンクタは、私たちのTOTALORDERに基づいて、昇順と降順と呼ばれる2つの機能で署名を定義していることがわかりますが定義。ファンクタは、そのようなシグネチャの実装をパラメータとして受け取ります。後で、それを使用して、strucの実装で、ペアを昇順または降順にソートします。
最終的に、aとbの型は、ファンクタに提供されたTOTALORDERの実装の要素の型によって異なります。
現在、以下のように異なるの比較タイプを使用して異なる実装を作成することができます。
structure StringComparator = MakeComparator(String)
structure IntegerComparator = MakeComparator(Integer)
そして、我々は彼らの種類とそれに対応し、それらを使用することができます。例えば:
val res01 = StringComparator.ascending("arm","house") (*(arm,house)*)
val res02 = StringComparator.descending("arm","house") (*(house,arm)*)
val res03 = IntegerComparator.ascending(1,2) (*(1,2)*)
val res04 = IntegerComparator.descending(1,2) (*(2,1)*)
それは型クラスでHaskellのような他の言語に比べて、確かに冗長だが、私はそれが問題を解決するための有効なアプローチだと考えています。
良いコメントと(明らかに)美しい論文ですが、OPの質問では、問題はオペレータがintでのみ定義されていることと関連があります。 (この反応が何らかの考え方にも合致しないとは言いませんが、確かにそうです!) –
ところで、あなたがそれを言いました(@aizen)、Ramsey博士の論文は "Theorems for free"誰にでも本当に素晴らしい読書! –