2014-06-17 25 views
1

我有實際價值的像[|1.2, 3.4, 5.3, 2.5|]SML NJ,能夠找到數組的最大實際,不能讓指數

fun max_arr arr = foldl Real.max (sub (arr, 0)) arr; 

工作正常的數組找到最大值5.3。 那麼我會想到像

fun max_arri arr = foldli (Real.max(sub (arr, 0))) arr; 

成功返回max value 2位置。但它不工作。

(Error: unbound variable or constructor: max_arri) 

我通過一切順利,我可以在網上找到,但文檔中關於sml seems small ... 根據手動他們都採取了相同的數據。所以我需要改變什麼?

foldli f init arr 
foldl f init arr 

還我不想因爲我改變了很多的數據

回答

1

他們不採取同樣的輸入使用列表。

foldl :: (  'a * 'b -> 'b) -> 'b -> 'a array -> 'b 
foldli :: (int * 'a * 'b -> 'b) -> 'b -> 'a array -> 'b 

正如我們可以從類型看到的,不同的是,foldli需要一個函數,也取整數 - 的元素的索引。

這兩個函數的返回類型都是'b,所以foldli不返回索引。相反,這種表達:

foldli (fn (i, a, b) => f (a, b)) init arr 

這是表達的完全等效:

foldl f init arr 

現在,如果我們想返回的元素的索引,我們需要'b到類型的foldli成爲int。但是,找到最大值依賴於元素的比較,所以我們也是需要當前的最大值,就像在你的max_arr函數中一樣。顯而易見的解決方案是使用元組。 'b現在變成(real * int)

(* cElem = current element 
* cI = current index 
*) 
fun fmax (i, elem : real, (cElem, cI)) = 
    if cElem > elem 
    then (cElem, cI) 
    else (elem, i) 

fun max_arri arr = foldli fmax (sub (arr, 0), 0) arr 

當然,這不是我們希望max_arri返回類型 - 我們只希望索引。鬆散的助手功能也不是很好,但作爲lambda有點長。相反,我們總結這一切在本地:

local 
    fun fmax (i, elem : real, (cElem, cI)) = 
    if cElem > elem 
    then (cElem, cI) 
    else (elem, i) 

    fun max_arri' arr = foldli fmax (sub (arr, 0), 0) arr 
in 
    fun max_arri arr = let val (_, i) = max_arri' arr 
        in i end 
end 
+0

對不起,如果我的跟進問題是愚蠢的,但是這是我第SML完整的程序。我得到語法錯誤 '錯誤:語法錯誤:刪除LPAREN WILD逗號 錯誤:語法錯誤:刪除ID RPAREN EQUALOP 在i結尾 結束 錯誤:語法錯誤:刪除IN ID END' –

+0

對不起,我沒有安裝在此計算機上的sml解釋器,所以代碼是未經測試。我會稍後再研究它,並讓你知道我找到了什麼。 – Tayacan

+0

我認爲這個問題爲fmax預計 'INT *「A *(INT * '一)' 在 '(I,ELEM,(切萊姆,CI))' 但它得到 '' 了' 從 'fmax sub(arr,0)' 仍然不知道如何解決它,雖然 –