简体   繁体   English

标准ML入门

[英]Getting started with Standard ML

I'm looking for some kind of "ML for beginners" guide - google has led me to some obscure mailing lists or way-over-my-head texts so far. 我正在寻找某种“适合初学者的ML”指南 - 谷歌带领我到目前为止一些不起眼的邮件列表或者我的头脑文本。

The problem is, I have zero functional programming experience so far, and wrapping my head around the concepts has turned out far more difficult than expected. 问题是,到目前为止我没有任何函数式编程经验,并且围绕这些概念的理解比预期的要困难得多。 For example, the task I'm trying to do now (yes, university :) ) is do a mapping between two lists (a,b) and (c,d), so that the result is a list of (a,d) from pairs where b = c. 例如,我现在要做的任务(是的,大学:))是在两个列表(a,b)和(c,d)之间进行映射,因此结果是(a,d)的列表)从b = c的对。

What I would ordinarily do is: 我通常会做的是:

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

But, I can't even get started with implementing something like that in SML. 但是,我甚至无法开始在SML中实现类似的东西。 For example, I know I could iterate over lists with nested map f list 's. 例如,我知道我可以使用嵌套map f list迭代列表。 However, the runtime (SML/NJ) will only accept this for functions that take only list element as parameter. 但是,运行时(SML / NJ)仅对仅将列表元素作为参数的函数接受此操作。 But how do I know what elements to return if I can only operate with one of the two lists at time? 但是,如果我只能在两个列表中的某个列表中运行,我怎么知道要返回哪些元素呢?

I am in desperate need of a resource that would go over this kind of thing, preferably with big friendly letters and lots of code examples :/ 我迫切需要一种能够解决这类问题的资源,最好是使用大量友好信件和大量代码示例:/

由CMU的Robert Harper教授编写的标准ML编程

I have some SML resources bookmarked: 我有一些书签的SML资源:

Programming in Standard ML '97: An On-line Tutorial 标准ML '97中的编程:在线教程
Elementary Standard ML (Amazon Kindle) 基本标准ML (亚马逊Kindle)
Elements of ML Programming (amazon.com) ML编程的元素 (amazon.com)

For the exercise that you mention, think of a function add that returns a new list instead of modifying the existing one, and consider how you would implement the exercise recursively in your favorite high-level language, that will be a first step. 对于您提到的练习,请考虑一个函数add ,它返回一个新列表而不是修改现有列表,并考虑如何以您喜欢的高级语言递归地实现练习,这将是第一步。

You don't need to use map or any other existing higher-order ML function! 您不需要使用map或任何其他现有的高阶ML功能! These are just shortcuts for experienced programmers. 这些只是有经验的程序员的捷径。 Use pattern-matching and recursion only. 仅使用模式匹配和递归。 But you can look at the implementation of functions such as map if you seek examples of well-used recursion and pattern-matching. 但是,如果您寻找使用良好的递归和模式匹配的示例,您可以查看map等函数的实现。

Recursing over multiple separate lists is messy (but might be what is wanted for this exercise, of course) - it's normally easier to make a single list from them both ("side by side", so in your case each entry would have a pair of integers) and then map or fold over that. 在多个单独的列表上递归是很混乱的(当然,这可能是本练习所需要的) - 通常更容易从它们中制作单个列表(“并排”,因此在您的情况下,每个条目都有一对整数)然后映射或折叠。 I suspect ML will have a function called something like "zip" which should get you started. 我怀疑ML会有一个叫做“zip”的函数,它可以让你开始。

Also, not really what you're looking for at the moment, but if you want a good ML book (it's actually a dialect of OCaml, but old enough to not be that different from SML) then look at Cousineau + Mauny. 此外,并不是你现在正在寻找的东西,但是如果你想要一本好的ML书(它实际上是OCaml的一种方言,但是已经足够老了,与SML没有什么不同)那么看看Cousineau + Mauny。 Maybe if you have some time in the holidays. 也许如果你在假期有一些时间。 It's a really good book - a bit like SICP, but for ML. 这是一本非常好的书 - 有点像SICP,但对于ML。

Do you understand what Currying is? 你明白Currying是什么吗?

For instance, do you understand the difference between 例如,你了解它们之间的区别

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

and

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

If you do, can you explain what 如果你这样做,你能解释一下吗?

val g = linearF(1.0,~1.0) ;

does? 呢?

Currying is NOT strictly necessary for solving your problem, but it IS a technique that is used a lot in functional programming. Currying并不是解决问题的必要条件,但它是一种在函数式编程中经常使用的技术。 In particular, it gives you a way to use List.map if you want. 特别是,如果需要,它为您提供了一种使用List.map的方法。 Here, you want to map over list1 but the function you want to use needs to know about list2 and the result of the computation. 在这里,您想要映射list1,但您想要使用的函数需要知道list2和计算结果。 This suggests that your code might have the shape 这表明您的代码可能具有该形状

List.map (f [] list2) list1

where f is some appropriately defined Curried function. 其中f是一些适当定义的Curried函数。 In general this is a useful trick for providing more information to a function that needs to be a "one argument" function for List.map -like reasons. 一般来说,这是一个有用的技巧,可以为需要为类似List.map的原因的“一个参数”函数的函数提供更多信息。

Does this help? 这有帮助吗?

Consider this following code of map2, this function does exactly what map does but with two lists. 考虑下面这个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;

Now you use it like this: 现在你像这样使用它:

- 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

Enjoy XD 享受XD

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM