我正在寻找某种“适合初学者的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)仅对仅将列表元素作为参数的函数接受此操作。但是,如果我只能在两个列表中的某个列表中运行,我怎么知道要返回哪些元素呢?
我迫切需要一种可以解决这类问题的资源,最好是使用大量友好信件和大量代码示例:/
答案 0 :(得分:8)
Programming in Standard ML由CMU的Robert Harper教授
答案 1 :(得分:5)
我有一些书签的SML资源:
Programming in Standard ML '97: An On-line Tutorial
Elementary Standard ML(亚马逊Kindle)
Elements of ML Programming(amazon.com)
答案 2 :(得分:2)
对于您提到的练习,请考虑一个函数add
,它返回一个新列表而不是修改现有列表,并考虑如何以您喜欢的高级语言递归地实现该练习,迈出第一步。
您无需使用map
或任何其他现有的高阶ML功能!这些只是有经验的程序员的捷径。仅使用模式匹配和递归。但是如果你寻找使用良好的递归和模式匹配的例子,你可以看看map
等函数的实现。
答案 3 :(得分:2)
对多个单独的列表进行递归是很混乱的(当然,这可能是本练习所需要的) - 通常更容易从它们中制作一个列表(“并排”,所以在你的情况下每个条目都会有一对整数)然后映射或折叠。我怀疑ML会有一个叫做“zip”的函数,它可以让你开始。
此外,并不是你现在正在寻找的东西,但是如果你想要一本好的ML书(它实际上是OCaml的方言,但是已经足够老了,与SML没那么不同)那么看看Cousineau + Mauny 。也许如果你在假期有一些时间。这是一本非常好的书 - 有点像SICP,但对于ML。
答案 4 :(得分:0)
你明白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 类似理由的“一个参数”函数。
这有帮助吗?
答案 5 :(得分:0)
考虑以下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