2012-03-15 26 views
1

我試圖做一個函數在標準的ML,需要2個參數,並返回一個布爾,和2參數可以是任何類型,在規範中它被寫爲'a * 'a -> bool,但每當我嘗試它,它使2參數自動整理。我怎樣才能讓這個函數有2個參數類型'a。在Standard ML中,如何定義'a *'a - > bool類型的函數?

以下是函數香港專業教育學院一直在努力執行:

fun lessThan (a, b) = 
    if a < b then true 
    else false; 

但是寫上述功能之後我得到的是:

val lessThan = fn : int * int -> bool 

,我想這是什麼:

val lessThan = fn : 'a * 'a -> bool 

我能做些什麼來使它工作?

回答

6

如果要使函數終止並返回一個值,Standard ML只有兩個函數'a * 'a -> bool。它們是

fun ktrue (_, _) = true 
fun kfalse (_, _) = false 

所有其他總,該類型的純函數是從上述兩個不可區分的。

而這兩個功能其實有更一般的型號'a * 'b -> bool

這實際上是編程語言理論的一個相當深入的結果。如果你想學習基礎知識,你可以嘗試閱讀John Reynolds關於表徵獨立性的工作或者Phil Wadler關於「自由定理」的着作。

+1

良好的評論,和(很明顯)是一個美麗的論文,但我認爲對於OP的問題,這個問題更多的是與操作符被單獨定義在整數。 (不是說這個迴應也不值得一些想法,它當然可以!) – 2012-03-18 08:47:01

+1

順便說一句,如果你提到它(@aizen),Ramsey博士的參考文獻是「自由定理」真正令人敬畏的閱讀給任何人! – 2012-03-18 08:53:04

0

我相信這是我們可以用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的類型類,但我認爲這是解決問題的有效方法。

相關問題