[英]Getting started with Standard ML
我正在尋找某種“適合初學者的ML”指南 - 谷歌帶領我到目前為止一些不起眼的郵件列表或者我的頭腦文本。
問題是,到目前為止我沒有任何函數式編程經驗,並且圍繞這些概念的理解比預期的要困難得多。 例如,我現在要做的任務(是的,大學:))是在兩個列表(a,b)和(c,d)之間進行映射,因此結果是(a,d)的列表)從b = c的對。
我通常會做的是:
result = []
for each x in list1 do
for each y in list2 do
if x.b == y.c result.add (x.a, y.d)
end
end
但是,我甚至無法開始在SML中實現類似的東西。 例如,我知道我可以使用嵌套map f list
迭代列表。 但是,運行時(SML / NJ)僅對僅將列表元素作為參數的函數接受此操作。 但是,如果我只能在兩個列表中的某個列表中運行,我怎么知道要返回哪些元素呢?
我迫切需要一種能夠解決這類問題的資源,最好是使用大量友好信件和大量代碼示例:/
由CMU的Robert Harper教授編寫的標准ML編程
我有一些書簽的SML資源:
標准ML '97中的編程:在線教程
基本標准ML (亞馬遜Kindle)
ML編程的元素 (amazon.com)
對於您提到的練習,請考慮一個函數add
,它返回一個新列表而不是修改現有列表,並考慮如何以您喜歡的高級語言遞歸地實現練習,這將是第一步。
您不需要使用map
或任何其他現有的高階ML功能! 這些只是有經驗的程序員的捷徑。 僅使用模式匹配和遞歸。 但是,如果您尋找使用良好的遞歸和模式匹配的示例,您可以查看map
等函數的實現。
在多個單獨的列表上遞歸是很混亂的(當然,這可能是本練習所需要的) - 通常更容易從它們中制作單個列表(“並排”,因此在您的情況下,每個條目都有一對整數)然后映射或折疊。 我懷疑ML會有一個叫做“zip”的函數,它可以讓你開始。
此外,並不是你現在正在尋找的東西,但是如果你想要一本好的ML書(它實際上是OCaml的一種方言,但是已經足夠老了,與SML沒有什么不同)那么看看Cousineau + Mauny。 也許如果你在假期有一些時間。 這是一本非常好的書 - 有點像SICP,但對於ML。
你明白Currying是什么嗎?
例如,你了解它們之間的區別
fun compute(m,b,x):real = m*x+b ;
和
fun linearF (m,b) x : real = m*x+b ;
如果你這樣做,你能解釋一下嗎?
val g = linearF(1.0,~1.0) ;
呢?
Currying並不是解決問題的必要條件,但它是一種在函數式編程中經常使用的技術。 特別是,如果需要,它為您提供了一種使用List.map的方法。 在這里,您想要映射list1,但您想要使用的函數需要知道list2和計算結果。 這表明您的代碼可能具有該形狀
List.map (f [] list2) list1
其中f是一些適當定義的Curried函數。 一般來說,這是一個有用的技巧,可以為需要為類似List.map的原因的“一個參數”函數的函數提供更多信息。
這有幫助嗎?
考慮下面這個map2的代碼,這個函數完全與map有關,但有兩個列表。
exception UnequalLengths;
fun map2(f,[],[]) = []
| map2(f,(a::s),(a'::s')) =
(f(a,a'))::(map2(f,s,s'))
| map2(f,s,s') = raise UnequalLengths;
fun plus(x,y) = x + y;
fun concat(s1,s2) = s1 ^ s2;
現在你像這樣使用它:
- map2(plus,[1,2,3],[4,5,6]);
val it = [5,7,9] : int list
- map2(concat,["a","b","c"],["d","e","f"]);
val it = ["ad","be","cf"] : string list
享受XD
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.