在SML

2013-10-22 33 views
3
fun Dbt (nil,_) = nil 
    | Dbt (x::xs,y::ys) = (x::y)::(Dbt(xs,ys)) 
    | Dbt (x::xs,nil) = [x]::(Dbt(xs,nil)); 

使用摺疊程序是否有使用高階和或在同級內置功能的非遞歸定義該功能的一種方式?我已經嘗試了所有我可以,但似乎我不會去任何地方。因爲你不消耗名單,但產生他們,你將無法使用通常的名單穿越運營商的任何想法可以理解的感謝..在SML

+0

這功課嗎? –

+0

我實際上想要使用這個函數來幫助我完成另一個更高階函數的定義,它不應該使用由個案或遞歸定義的函數。換句話說,我想在我的'foldr'函數部分中將它作爲迭代器作業,是的 – Emma

回答

4

(地圖,過濾器,倍...) 。

沒有爲列表產生然而一個共同的和易於理解的組合子,這是

val unfold : ('a -> ('a * 'b) option) -> 'a -> 'b list 

不幸的是,這算不算在基本SML庫,所以你可能要自己定義。

fun Dbt (xs, ys) = 
    let fun Step (nil, _) = NONE 
     | Step (x::xs, y::ys) = SOME (x::y,(xs,ys)) 
     | Step (x::xs, nil) = SOME ([x], (xs,nil)) 
    in unfold Step (xs, ys) 
+0

我想弄明白這一點,但是我有點困惑於let表達式的結構。真的是一步嗎?它看起來像我的Dbt,你能解釋一下嗎? – Emma

+0

'Step'確實具有'Dbt'的所有有用內容,但它不是遞歸的。這個想法是,它實現了計算的「一步」,返回列表的下一個元素應該是什麼(在輸入的函數中,你可以想象在列表生成期間轉換的狀態)。你應該嘗試從我給出的類型簽名中寫出(遞歸)combinator'unfold',通過將它們組合在一起,你將能夠更好地理解'Step'。 – gasche

+2

你可能不想聲明三個不同的叫做'Step'的函數,而是有三個不同的函數(使用'| Step(x :: xs ...')(我會修復這個問題,但顯然StackOverflow贏了' t容易讓我。) –