我相信這是我們可以用SML中的函數來解決的那類問題。
例如,考慮一個名爲TOTALORDER的簽名的存在,它在問題中定義了你的函數(lt表示低於)。
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簽名定義。仿函數作爲參數接收這種簽名的實現。後來它使用它,在結構實現中按照升序或降序排序一對。
因此,最終,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的問題,這個問題更多的是與操作符被單獨定義在整數。 (不是說這個迴應也不值得一些想法,它當然可以!) – 2012-03-18 08:47:01
順便說一句,如果你提到它(@aizen),Ramsey博士的參考文獻是「自由定理」真正令人敬畏的閱讀給任何人! – 2012-03-18 08:53:04