Functional programming 开始使用标准ML

Functional programming 开始使用标准ML,functional-programming,sml,ml,Functional Programming,Sml,Ml,我正在寻找某种类型的“ML初学者”指南——到目前为止,谷歌已经让我找到了一些晦涩难懂的邮件列表或是一些超出我理解范围的文字 问题是,到目前为止,我没有任何函数式编程经验,而将我的头脑集中在这些概念上,结果比预期的要困难得多。例如,我现在要做的任务(是的,大学:)是在两个列表(a,b)和(c,d)之间进行映射,这样结果就是一个(a,d)列表,其中b=c 我通常会做的是: result = [] for each x in list1 do for each y in list2 do

我正在寻找某种类型的“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中实现类似的东西。例如,我知道我可以使用嵌套的
映射f list
遍历列表。但是,运行时(SML/NJ)将只接受仅使用列表元素作为参数的函数的此选项。但是,如果一次只能使用两个列表中的一个进行操作,那么如何知道返回哪些元素呢


我非常需要一个资源来处理这类事情,最好是用友好的大字和大量的代码示例:/

我有一些SML资源书签:


(亚马逊Kindle)

(Amazon .com)

< p>对于你提到的练习,考虑函数<代码> Addio>代码>,它返回一个新的列表,而不是修改现有的列表,并考虑如何在你最喜欢的高级语言中递归地执行练习,这将是第一步。
您不需要使用
map
或任何其他现有的高阶ML函数!这些只是经验丰富的程序员的捷径。仅使用模式匹配和递归。但是,如果您寻找使用良好的递归和模式匹配的示例,您可以查看函数的实现,例如
map

在多个单独的列表上递归是混乱的(当然,这可能是本练习所需要的)-通常更容易从这两个列表中创建一个单独的列表(“并排”),因此在您的示例中,每个条目都有一对整数),然后映射或折叠它。我怀疑ML将有一个名为“zip”之类的函数,应该可以让您开始使用它


另外,这并不是你现在想要的,但是如果你想要一本好的ML书籍(它实际上是OCaml的一种方言,但已经足够老了,与SML没有什么不同),那么看看Cousineau+Mauny。如果你假期有时间的话。这是一本非常好的书,有点像SICP,但对于ML来说,是CMU的罗伯特·哈珀教授写的。

你知道什么是咖喱吗

例如,你是否理解两者之间的区别

fun compute(m,b,x):real = m*x+b ;

如果你这样做了,你能解释一下吗

val g = linearF(1.0,~1.0) ;
是吗

咖喱对于解决您的问题并不是绝对必要的,但它是函数式编程中经常使用的一种技术。特别是,如果需要,它提供了一种使用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

hmmm。。。在反思时,使用List.foldr或List.foldl代替List.map更有可能得到一个简单的解决方案。
- 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