Haskell或标准ML适合初学者?

时间:2022-04-10 16:44:00

I'm going to be teaching a lower-division course in discrete structures. I have selected the text book Discrete Structures, Logic, and Computability in part because it contains examples and concepts that are conducive to implementation with a functional programming language. (I also think it's a good textbook.)

我将在离散结构中教一个低级课程。我选择了教科书“离散结构,逻辑和可计算性”,因为它包含有助于使用函数式编程语言实现的示例和概念。 (我也认为这是一本很好的教科书。)

I want an easy-to-understand FP language to illustrate DS concepts and that the students can use. Most students will have had only one or two semesters of programming in Java, at best. After looking at Scheme, Erlang, Haskell, Ocaml, and SML, I've settled on either Haskell or Standard ML. I'm leaning towards Haskell for the reasons outlined below, but I'd like the opinion of those who are active programmers in one or the other.

我想要一个易于理解的FP语言来说明DS概念以及学生可以使用的。大多数学生最多只能用一到两个学期的Java编程。在查看Scheme,Erlang,Haskell,Ocaml和SML之后,我已经确定了Haskell或Standard ML。由于下面列出的原因,我倾向于Haskell,但我喜欢那些在一个或那个中活跃的程序员的意见。

  • Both Haskell and SML have pattern matching which makes describing a recursive algorithm a cinch.
  • Haskell和SML都具有模式匹配,这使得描述递归算法变得简单。

  • Haskell has nice list comprehensions that match nicely with the way such lists are expressed mathematically.
  • Haskell有很好的列表推导,可以很好地匹配这些列表以数学方式表达的方式。

  • Haskell has lazy evaluation. Great for constructing infinite lists using the list comprehension technique.
  • Haskell有懒惰的评价。非常适合使用列表理解技术构建无限列表。

  • SML has a truly interactive interpreter in which functions can be both defined and used. In Haskell, functions must be defined in a separate file and compiled before being used in the interactive shell.
  • SML有一个真正的交互式解释器,可以在其中定义和使用函数。在Haskell中,函数必须在单独的文件中定义,并在交互式shell中使用之前进行编译。

  • SML gives explicit confirmation of the function argument and return types in a syntax that's easy to understand. For example: val foo = fn : int * int -> int. Haskell's implicit curry syntax is a bit more obtuse, but not totally alien. For example: foo :: Int -> Int -> Int.
  • SML以易于理解的语法明确确认函数参数和返回类型。例如:val foo = fn:int * int - > int。 Haskell的隐式咖喱语法有点迟钝,但并非完全陌生。例如:foo :: Int - > Int - > Int。

  • Haskell uses arbitrary-precision integers by default. It's an external library in SML/NJ. And SML/NJ truncates output to 70 characters by default.
  • Haskell默认使用任意精度的整数。它是SML / NJ中的外部库。并且SML / NJ默认将输出截断为70个字符。

  • Haskell's lambda syntax is subtle -- it uses a single backslash. SML is more explicit. Not sure if we'll ever need lambda in this class, though.
  • Haskell的lambda语法很微妙 - 它使用单个反斜杠。 SML更明确。但是不确定我们是否会在这堂课中需要lambda。

Essentially, SML and Haskell are roughly equivalent. I lean toward Haskell because I'm loving the list comprehensions and infinite lists in Haskell. But I'm worried that the extensive number of symbols in Haskell's compact syntax might cause students problems. From what I've gathered reading other posts on SO, Haskell is not recommended for beginners starting out with FP. But we're not going to be building full-fledged applications, just trying out simple algorithms.

从本质上讲,SML和Haskell大致相同。我倾向于Haskell,因为我喜欢Haskell中的列表理解和无限列表。但我担心Haskell紧凑语法中的大量符号可能会导致学生出现问题。从我收集到的关于SO的其他帖子开始,Haskell不建议初学者从FP开始。但我们不打算构建成熟的应用程序,只是尝试简单的算法。

What do you think?

你怎么看?


Edit: Upon reading some of your great responses, I should clarify some of my bullet points.

编辑:在阅读了一些很好的回复后,我应该澄清一些我的要点。

In SML, there's no syntactic distinction between defining a function in the interpreter and defining it in an external file. Let's say you want to write the factorial function. In Haskell you can put this definition into a file and load it into GHCi:

在SML中,在解释器中定义函数和在外部文件中定义函数之间没有语法上的区别。假设您要编写阶乘函数。在Haskell中,您可以将此定义放入文件中并将其加载到GHCi中:

fac 0 = 1
fac n = n * fac (n-1)

To me, that's clear, succinct, and matches the mathematical definition in the book. But if you want to write the function in GHCi directly, you have to use a different syntax:

对我来说,这很清楚,简洁,并且符合书中的数学定义。但是如果你想直接在GHCi中编写函数,你必须使用不同的语法:

let fac 0 = 1; fac n = n * fac (n-1)

When working with interactive interpreters, from a teaching perspective it's very, very handy when the student can use the same code in both a file and the command line.

在使用交互式口译员时,从教学角度来看,当学生在文件和命令行中使用相同的代码时,非常非常方便。

By "explicit confirmation of the function," I meant that upon defining the function, SML right away tells you the name of the function, the types of the arguments, and the return type. In Haskell you have to use the :type command and then you get the somewhat confusing curry notation.

通过“对函数的显式确认”,我的意思是在定义函数时,SML立即告诉您函数的名称,参数的类型和返回类型。在Haskell中你必须使用:type命令,然后你会得到一些有点令人困惑的咖喱符号。

One more cool thing about Haskell -- this is a valid function definition:

关于Haskell的一个更酷的事情 - 这是一个有效的函数定义:

fac 0 = 1
fac (n+1) = (n+1) * fac n

Again, this matches a definition they might find in the textbook. Can't do that in SML!

同样,这与他们可能在教科书中找到的定义相匹配。在SML中无法做到这一点!

8 个解决方案

#1


Much as I love Haskell, here are the reasons I would prefer SML for a class in discrete math and data structures (and most other beginners' classes):

就像我喜欢Haskell一样,以下是我更喜欢SML用于离散数学和数据结构(以及大多数其他初学者类)的类的原因:

  • Time and space costs of Haskell programs can be very hard to predict, even for experts. SML offers much more limited ways to blow the machine.

    即使对于专家来说,Haskell程序的时间和空间成本也很难预测。 SML提供了更有限的方式来吹制机器。

  • Syntax for function defintion in an interactive interpreter is identical to syntax used in a file, so you can cut and paste.

    交互式解释器中的函数定义语法与文件中使用的语法相同,因此您可以剪切和粘贴。

  • Although operator overloading in SML is totally bogus, it is also simple. It's going to be hard to teach a whole class in Haskell without having to get into type classes.

    尽管SML中的运算符重载完全是假的,但它也很简单。在不必进入类型类的情况下,很难在Haskell中教授整个类。

  • Student can debug using print. (Although, as a commenter points out, it is possible to get almost the same effect in Haskell using Debug.Trace.trace.)

    学生可以使用打印调试。 (虽然,正如评论者指出的那样,使用Debug.Trace.trace可以在Haskell中获得几乎相同的效果。)

  • Infinite data structures blow people's minds. For beginners, you're better off having them define a stream type complete with ref cells and thunks, so they know how it works:

    无限的数据结构打动了人们的思想。对于初学者来说,最好让他们定义一个带有ref单元格和thunk的流类型,这样他们就知道它是如何工作的:

    datatype 'a thunk_contents = UNEVALUATED of unit -> 'a
                               | VALUE of 'a
    type 'a thunk = 'a thunk_contents ref
    val delay : (unit -> 'a) -> 'a thunk
    val force : 'a thunk -> 'a
    

    Now it's not magic any more, and you can go from here to streams (infinite lists).

    现在它不再是魔法了,你可以从这里到流(无限列表)。

  • Layout is not as simple as in Python and can be confusing.

    布局不像Python那么简单,可能会令人困惑。

There are two places Haskell has an edge:

Haskell有两个优势:

  • In core Haskell you can write a function's type signature just before its definition. This is hugely helpful for students and other beginners. There just isn't a nice way to deal with type signatures in SML.

    在核心Haskell中,您可以在定义之前编写函数的类型签名。这对学生和其他初学者非常有帮助。在SML中处理类型签名并不是一种好方法。

  • Haskell has better concrete syntax. The Haskell syntax is a major improvement over ML syntax. I have written a short note about when to use parentheses in an ML program; this helps a little.

    Haskell具有更好的具体语法。 Haskell语法是对ML语法的重大改进。我写了一篇关于何时在ML程序中使用括号的简短说明;这有点帮助。

Finally, there is a sword that cuts both ways:

最后,有一把剑可以削减两种方式:

  • Haskell code is pure by default, so your students are unlikely to stumble over impure constructs (IO monad, state monad) by accident. But by the same token, they can't print, and if you want to do I/O then at minumum you have to explain do notation, and return is confusing.
  • Haskell代码默认是纯粹的,所以你的学生不太可能偶然发现不纯的结构(IO monad,state monad)。但是出于同样的原因,它们无法打印,如果你想做I / O,那么在最低限度你必须解释做符号,并且返回是令人困惑的。


On a related topic, here is some advice for your course preparation: don't overlook Purely Functional Data Structures by Chris Okasaki. Even if you don't have your students use it, you will definitely want to have a copy.

在相关主题中,这里有一些关于课程准备的建议:不要忽视Chris Okasaki的Purely Functional Data Structures。即使您没有让学生使用它,您也一定要复印一份。

#2


We teach Haskell to first years at our university. My feelings about this are a bit mixed. On the one hand teaching Haskell to first years means they don't have to unlearn the imperative style. Haskell can also produce very concise code which people who had some Java before can appreciate.

我们在大学的第一年教Haskell。我对此的看法有点混乱。一方面教Haskell到头几年意味着他们不必忘记命令式的风格。 Haskell也可以生成非常简洁的代码,以前有过Java的人可以欣赏它们。

Some problems I've noticed students often have:

我注意到学生经常遇到的一些问题:

  • Pattern matching can be a bit difficult, at first. Students initially had some problems seeing how value construction and pattern matching are related. They also had some problems distinguishing between abstractions. Our exercises included writing functions that simplify arithmetic expression and some students had difficulty seeing the difference between the abstract representation (e.g., Const 1) and the meta-language representation (1).

    首先,模式匹配可能有点困难。学生最初在看到价值构建和模式匹配是如何相关时遇到了一些问题。他们在区分抽象方面也存在一些问题。我们的练习包括编写简化算术表达的函数,一些学生很难看到抽象表示(例如,Const 1)和元语言表示(1)之间的差异。

    Furthermore, if your students are supposed to write list processing functions themselves, be careful pointing out the difference between the patterns

    此外,如果您的学生应该自己编写列表处理功能,请注意指出模式之间的差异

    []
    [x]
    (x:xs)
    [x:xs]
    

    Depending on how much functional programming you want to teach them on the way, you may just give them a few library functions and let them play around with that.

    根据您想要在途中教授多少函数式编程,您可以给它们一些库函数,让它们随意使用它们。

  • We didn't teach our students about anonymous functions, we simply told them about where clauses. For some tasks this was a bit verbose, but worked well otherwise. We also didn't tell them about partial applications; this is probably quite easy to explain in Haskell (due to its form of writing types) so it might be worth showing to them.

    我们没有教我们的学生匿名功能,我们只是告诉他们哪里有条款。对于某些任务,这有​​点冗长,但其他方面效果不错。我们也没有告诉他们部分申请;这可能很容易在Haskell中解释(由于它的写入类型),所以它可能值得向他们展示。

  • They quickly discovered list comprehensions and preferred them over higher-order functions like filter, map, zipWith.

    他们很快就发现了列表推导,并优先于高阶函数,如filter,map,zipWith。

  • I think we missed out a bit on teaching them how to let them guide their thoughts by the types. I'm not quite sure, though, whether this is helpful to beginners or not.

    我想我们错过了教他们如何让他们按类型引导他们的想法。不过,我不太确定这对初学者是否有帮助。

  • Error messages are usually not very helpful to beginners, they might occasionally need some help with these. I haven't tried it myself, but there's a Haskell compiler specifically targeted at newcomers, mainly by means of better error messages: Helium

    错误消息通常对初学者没有太大帮助,他们可能偶尔需要一些帮助。我自己没有尝试过,但是有一个专门针对新手的Haskell编译器,主要是通过更好的错误消息:Helium

  • For the small programs, things like possible space leaks weren't an issue.

    对于小型程序,可能的空间泄漏等问题不是问题。

Overall, Haskell is a good teaching language, but there are a few pitfalls. Given that students feel a lot more comfortable with list comprehensions than higher-order functions, this might be the argument you need. I don't know how long your course is or how much programming you want to teach them, but do plan some time for teaching them basic concepts--they will need it.

总的来说,Haskell是一种很好的教学语言,但有一些陷阱。鉴于学生对列表推导感觉比高阶函数更舒服,这可能是您需要的论据。我不知道你的课程有多长,或者你想教他们多少编程,但是要花些时间教他们基本概念 - 他们需要它。

#3


BTW,

# SML has a truly interactive interpreter in which functions can be both defined and used. In Haskell, functions must be defined in a separate file and compiled before being used in the interactive shell.

#SML有一个真正的交互式解释器,可以在其中定义和使用函数。在Haskell中,函数必须在单独的文件中定义,并在交互式shell中使用之前进行编译。

Is inaccurate. Use GHCi:

不准确。使用GHCi:

Prelude> let f x = x ^ 2
Prelude> f 7
49
Prelude> f 2
4

There are also good resources for Haskell in education on the haskell.org edu. page, with experiences from different teachers. http://haskell.org/haskellwiki/Haskell_in_education

在haskell.org edu上,Haskell在教育方面也有很好的资源。页面,来自不同老师的经验。 http://haskell.org/haskellwiki/Haskell_in_education

Finally, you'll be able to teach them multicore parallelism just for fun, if you use Haskell :-)

最后,如果你使用Haskell,你将能够教他们多核并行,只是为了好玩:-)

#4


Many universities teach Haskell as a first functional language or even a first programming language, so I don't think this will be a problem.

许多大学将Haskell教授为第一种功能语言甚至是第一种编程语言,因此我认为这不会成为一个问题。

Having done some of the teaching on one such course, I don't agree that the possible confusions you identify are that likely. The most likely sources of early confusion are parsing errors caused by bad layout, and mysterious messages about type classes when numeric literals are used incorrectly.

在一门这样的课程上完成了一些教学,我不同意你认识到的可能的混淆。早期混淆的最可能的来源是解析由错误布局引起的错误,以及在错误地使用数字文字时关于类型类的神秘消息。

I'd also disagree with any suggestion that Haskell is not recommended for beginners starting out with FP. It's certainly the big bang approach in ways that strict languages with mutation aren't, but I think that's a very valid approach.

我也不同意任何关于Haskell不建议初学者开始使用FP的建议。当然,突变的严格语言并不是一种大爆炸方法,但我认为这是一种非常有效的方法。

#5


  • SML has a truly interactive interpreter in which functions can be both defined and used. In Haskell, functions must be defined in a separate file and compiled before being used in the interactive shell.
  • SML有一个真正的交互式解释器,可以在其中定义和使用函数。在Haskell中,函数必须在单独的文件中定义,并在交互式shell中使用之前进行编译。

While Hugs may have that limitation, GHCi does not:

虽然拥抱可能有这种限制,但GHCi不会:

$ ghci
GHCi, version 6.10.1: http://www.haskell.org/ghc/  :? for help
Loading package ghc-prim ... linking ... done.
Loading package integer ... linking ... done.
Loading package base ... linking ... done.
Prelude> let hello name = "Hello, " ++ name
Prelude> hello "Barry"
"Hello, Barry"

There's many reasons I prefer GHC(i) over Hugs, this is just one of them.

我喜欢GHC(i)而不是Hugs的原因有很多,这只是其中之一。

  • SML gives explicit confirmation of the function argument and return types in a syntax that's easy to understand. For example: val foo = fn : int * int -> int. Haskell's implicit curry syntax is a bit more obtuse, but not totally alien. For example: foo :: Int -> Int -> Int.
  • SML以易于理解的语法明确确认函数参数和返回类型。例如:val foo = fn:int * int - > int。 Haskell的隐式咖喱语法有点迟钝,但并非完全陌生。例如:foo :: Int - > Int - > Int。

SML has what you call "implicit curry" syntax as well.

SML也有你所谓的“隐式咖喱”语法。

$ sml
Standard ML of New Jersey v110.69 [built: Fri Mar 13 16:02:47 2009]
- fun add x y = x + y;
val add = fn : int -> int -> int

Essentially, SML and Haskell are roughly equivalent. I lean toward Haskell because I'm loving the list comprehensions and infinite lists in Haskell. But I'm worried that the extensive number of symbols in Haskell's compact syntax might cause students problems. From what I've gathered reading other posts on SO, Haskell is not recommended for beginners starting out with FP. But we're not going to be building full-fledged applications, just trying out simple algorithms.

从本质上讲,SML和Haskell大致相同。我倾向于Haskell,因为我喜欢Haskell中的列表理解和无限列表。但我担心Haskell紧凑语法中的大量符号可能会导致学生出现问题。从我收集到的关于SO的其他帖子开始,Haskell不建议初学者从FP开始。但我们不打算构建成熟的应用程序,只是尝试简单的算法。

I like using Haskell much more than SML, but I would still teach SML first.

我喜欢使用Haskell比SML更多,但我仍然会先教SML。

  • Seconding nominolo's thoughts, list comprehensions do seem to slow students from getting to some higher-order functions.
  • 借调nominolo的想法,列表推理确实会让学生放慢一些高阶函数的速度。

  • If you want laziness and infinite lists, it's instructive to implement it explicitly.
  • 如果你想要懒惰和无限列表,明确地实现它是有益的。

  • Because SML is eagerly evaluated, the execution model is far easier to comprehend, and "debugging via printf" works a lot better than in Haskell.
  • 因为热切地评估了SML,所以执行模型更容易理解,并且“通过printf调试”比Haskell更好地工作。

  • SML's type system is also simpler. While your class likely wouldn't use them anyways, Haskell's typeclasses are still an extra bump to get over -- getting them to understand the 'a versus ''a distinction in SML is tough enough.
  • SML的类型系统也更简单。虽然你的课程可能不会使用它们,但Haskell的类型类仍然是一个额外的碰撞 - 让他们理解“a对”在SML中的区别是非常困难的。

#6


Most answers were technical, but I think you should consider at least one that is not: Haskell (as OCaml), at this time, has a bigger community using it in a wider range of contexts. There's also a big database of libraries and applications written for profit and fun at Hackage. That may be an important factor in keeping some of your students using the language after your course is finished, and maybe trying other functional languages (like Standard ML) later.

大多数答案都是技术性的,但我认为你应该考虑至少一个不是:Haskell(作为OCaml),在这个时候,有一个更大的社区在更广泛的背景下使用它。还有一个庞大的图书馆和应用程序数据库,为Hackage的利润和乐趣而编写。这可能是让您的学生在课程结束后使用该语言的一个重要因素,也许可以在以后尝试其他功能语言(如标准ML)。

#7


I am amazed you are not considering OCaml and F# given that they address so many of your concerns. Surely decent and helpful development environments are a high priority for learners? SML is way behind and F# is way ahead of all other FPLs in that respect.

我很惊讶你不考虑OCaml和F#,因为它们解决了你的许多问题。当然,体面和有益的开发环境是学习者的首要任务吗?在这方面,SML远远落后于所有其他FPL。

Also, both OCaml and F# have list comprehensions.

此外,OCaml和F#都有列表推导。

#8


Haskell. I'm ahead in my algos/theory class in CS because of the stuff I learned from using Haskell. It's such a comprehensive language, and it will teach you a ton of CS, just by using it.

哈斯克尔。由于我从使用Haskell学到的东西,我在CS的算法/理论课中领先。它是如此全面的语言,只需使用它就可以教你大量的CS。

However, SML is much easier to learn. Haskell has features such as lazy evaluation and control structures that make it much more powerful, but with the cost of a steep(ish) learning curve. SML has no such curve.

但是,SML更容易学习。 Haskell具有惰性评估和控制结构等功能,使其功能更强大,但成本却是陡峭(ish)的学习曲线。 SML没有这样的曲线。

That said, most of Haskell was unlearning stuff from less scientific/mathematic languages such as Ruby, ObjC, or Python.

也就是说,Haskell的大部分内容都来自于较少科学/数学语言,如Ruby,ObjC或Python。

#1


Much as I love Haskell, here are the reasons I would prefer SML for a class in discrete math and data structures (and most other beginners' classes):

就像我喜欢Haskell一样,以下是我更喜欢SML用于离散数学和数据结构(以及大多数其他初学者类)的类的原因:

  • Time and space costs of Haskell programs can be very hard to predict, even for experts. SML offers much more limited ways to blow the machine.

    即使对于专家来说,Haskell程序的时间和空间成本也很难预测。 SML提供了更有限的方式来吹制机器。

  • Syntax for function defintion in an interactive interpreter is identical to syntax used in a file, so you can cut and paste.

    交互式解释器中的函数定义语法与文件中使用的语法相同,因此您可以剪切和粘贴。

  • Although operator overloading in SML is totally bogus, it is also simple. It's going to be hard to teach a whole class in Haskell without having to get into type classes.

    尽管SML中的运算符重载完全是假的,但它也很简单。在不必进入类型类的情况下,很难在Haskell中教授整个类。

  • Student can debug using print. (Although, as a commenter points out, it is possible to get almost the same effect in Haskell using Debug.Trace.trace.)

    学生可以使用打印调试。 (虽然,正如评论者指出的那样,使用Debug.Trace.trace可以在Haskell中获得几乎相同的效果。)

  • Infinite data structures blow people's minds. For beginners, you're better off having them define a stream type complete with ref cells and thunks, so they know how it works:

    无限的数据结构打动了人们的思想。对于初学者来说,最好让他们定义一个带有ref单元格和thunk的流类型,这样他们就知道它是如何工作的:

    datatype 'a thunk_contents = UNEVALUATED of unit -> 'a
                               | VALUE of 'a
    type 'a thunk = 'a thunk_contents ref
    val delay : (unit -> 'a) -> 'a thunk
    val force : 'a thunk -> 'a
    

    Now it's not magic any more, and you can go from here to streams (infinite lists).

    现在它不再是魔法了,你可以从这里到流(无限列表)。

  • Layout is not as simple as in Python and can be confusing.

    布局不像Python那么简单,可能会令人困惑。

There are two places Haskell has an edge:

Haskell有两个优势:

  • In core Haskell you can write a function's type signature just before its definition. This is hugely helpful for students and other beginners. There just isn't a nice way to deal with type signatures in SML.

    在核心Haskell中,您可以在定义之前编写函数的类型签名。这对学生和其他初学者非常有帮助。在SML中处理类型签名并不是一种好方法。

  • Haskell has better concrete syntax. The Haskell syntax is a major improvement over ML syntax. I have written a short note about when to use parentheses in an ML program; this helps a little.

    Haskell具有更好的具体语法。 Haskell语法是对ML语法的重大改进。我写了一篇关于何时在ML程序中使用括号的简短说明;这有点帮助。

Finally, there is a sword that cuts both ways:

最后,有一把剑可以削减两种方式:

  • Haskell code is pure by default, so your students are unlikely to stumble over impure constructs (IO monad, state monad) by accident. But by the same token, they can't print, and if you want to do I/O then at minumum you have to explain do notation, and return is confusing.
  • Haskell代码默认是纯粹的,所以你的学生不太可能偶然发现不纯的结构(IO monad,state monad)。但是出于同样的原因,它们无法打印,如果你想做I / O,那么在最低限度你必须解释做符号,并且返回是令人困惑的。


On a related topic, here is some advice for your course preparation: don't overlook Purely Functional Data Structures by Chris Okasaki. Even if you don't have your students use it, you will definitely want to have a copy.

在相关主题中,这里有一些关于课程准备的建议:不要忽视Chris Okasaki的Purely Functional Data Structures。即使您没有让学生使用它,您也一定要复印一份。

#2


We teach Haskell to first years at our university. My feelings about this are a bit mixed. On the one hand teaching Haskell to first years means they don't have to unlearn the imperative style. Haskell can also produce very concise code which people who had some Java before can appreciate.

我们在大学的第一年教Haskell。我对此的看法有点混乱。一方面教Haskell到头几年意味着他们不必忘记命令式的风格。 Haskell也可以生成非常简洁的代码,以前有过Java的人可以欣赏它们。

Some problems I've noticed students often have:

我注意到学生经常遇到的一些问题:

  • Pattern matching can be a bit difficult, at first. Students initially had some problems seeing how value construction and pattern matching are related. They also had some problems distinguishing between abstractions. Our exercises included writing functions that simplify arithmetic expression and some students had difficulty seeing the difference between the abstract representation (e.g., Const 1) and the meta-language representation (1).

    首先,模式匹配可能有点困难。学生最初在看到价值构建和模式匹配是如何相关时遇到了一些问题。他们在区分抽象方面也存在一些问题。我们的练习包括编写简化算术表达的函数,一些学生很难看到抽象表示(例如,Const 1)和元语言表示(1)之间的差异。

    Furthermore, if your students are supposed to write list processing functions themselves, be careful pointing out the difference between the patterns

    此外,如果您的学生应该自己编写列表处理功能,请注意指出模式之间的差异

    []
    [x]
    (x:xs)
    [x:xs]
    

    Depending on how much functional programming you want to teach them on the way, you may just give them a few library functions and let them play around with that.

    根据您想要在途中教授多少函数式编程,您可以给它们一些库函数,让它们随意使用它们。

  • We didn't teach our students about anonymous functions, we simply told them about where clauses. For some tasks this was a bit verbose, but worked well otherwise. We also didn't tell them about partial applications; this is probably quite easy to explain in Haskell (due to its form of writing types) so it might be worth showing to them.

    我们没有教我们的学生匿名功能,我们只是告诉他们哪里有条款。对于某些任务,这有​​点冗长,但其他方面效果不错。我们也没有告诉他们部分申请;这可能很容易在Haskell中解释(由于它的写入类型),所以它可能值得向他们展示。

  • They quickly discovered list comprehensions and preferred them over higher-order functions like filter, map, zipWith.

    他们很快就发现了列表推导,并优先于高阶函数,如filter,map,zipWith。

  • I think we missed out a bit on teaching them how to let them guide their thoughts by the types. I'm not quite sure, though, whether this is helpful to beginners or not.

    我想我们错过了教他们如何让他们按类型引导他们的想法。不过,我不太确定这对初学者是否有帮助。

  • Error messages are usually not very helpful to beginners, they might occasionally need some help with these. I haven't tried it myself, but there's a Haskell compiler specifically targeted at newcomers, mainly by means of better error messages: Helium

    错误消息通常对初学者没有太大帮助,他们可能偶尔需要一些帮助。我自己没有尝试过,但是有一个专门针对新手的Haskell编译器,主要是通过更好的错误消息:Helium

  • For the small programs, things like possible space leaks weren't an issue.

    对于小型程序,可能的空间泄漏等问题不是问题。

Overall, Haskell is a good teaching language, but there are a few pitfalls. Given that students feel a lot more comfortable with list comprehensions than higher-order functions, this might be the argument you need. I don't know how long your course is or how much programming you want to teach them, but do plan some time for teaching them basic concepts--they will need it.

总的来说,Haskell是一种很好的教学语言,但有一些陷阱。鉴于学生对列表推导感觉比高阶函数更舒服,这可能是您需要的论据。我不知道你的课程有多长,或者你想教他们多少编程,但是要花些时间教他们基本概念 - 他们需要它。

#3


BTW,

# SML has a truly interactive interpreter in which functions can be both defined and used. In Haskell, functions must be defined in a separate file and compiled before being used in the interactive shell.

#SML有一个真正的交互式解释器,可以在其中定义和使用函数。在Haskell中,函数必须在单独的文件中定义,并在交互式shell中使用之前进行编译。

Is inaccurate. Use GHCi:

不准确。使用GHCi:

Prelude> let f x = x ^ 2
Prelude> f 7
49
Prelude> f 2
4

There are also good resources for Haskell in education on the haskell.org edu. page, with experiences from different teachers. http://haskell.org/haskellwiki/Haskell_in_education

在haskell.org edu上,Haskell在教育方面也有很好的资源。页面,来自不同老师的经验。 http://haskell.org/haskellwiki/Haskell_in_education

Finally, you'll be able to teach them multicore parallelism just for fun, if you use Haskell :-)

最后,如果你使用Haskell,你将能够教他们多核并行,只是为了好玩:-)

#4


Many universities teach Haskell as a first functional language or even a first programming language, so I don't think this will be a problem.

许多大学将Haskell教授为第一种功能语言甚至是第一种编程语言,因此我认为这不会成为一个问题。

Having done some of the teaching on one such course, I don't agree that the possible confusions you identify are that likely. The most likely sources of early confusion are parsing errors caused by bad layout, and mysterious messages about type classes when numeric literals are used incorrectly.

在一门这样的课程上完成了一些教学,我不同意你认识到的可能的混淆。早期混淆的最可能的来源是解析由错误布局引起的错误,以及在错误地使用数字文字时关于类型类的神秘消息。

I'd also disagree with any suggestion that Haskell is not recommended for beginners starting out with FP. It's certainly the big bang approach in ways that strict languages with mutation aren't, but I think that's a very valid approach.

我也不同意任何关于Haskell不建议初学者开始使用FP的建议。当然,突变的严格语言并不是一种大爆炸方法,但我认为这是一种非常有效的方法。

#5


  • SML has a truly interactive interpreter in which functions can be both defined and used. In Haskell, functions must be defined in a separate file and compiled before being used in the interactive shell.
  • SML有一个真正的交互式解释器,可以在其中定义和使用函数。在Haskell中,函数必须在单独的文件中定义,并在交互式shell中使用之前进行编译。

While Hugs may have that limitation, GHCi does not:

虽然拥抱可能有这种限制,但GHCi不会:

$ ghci
GHCi, version 6.10.1: http://www.haskell.org/ghc/  :? for help
Loading package ghc-prim ... linking ... done.
Loading package integer ... linking ... done.
Loading package base ... linking ... done.
Prelude> let hello name = "Hello, " ++ name
Prelude> hello "Barry"
"Hello, Barry"

There's many reasons I prefer GHC(i) over Hugs, this is just one of them.

我喜欢GHC(i)而不是Hugs的原因有很多,这只是其中之一。

  • SML gives explicit confirmation of the function argument and return types in a syntax that's easy to understand. For example: val foo = fn : int * int -> int. Haskell's implicit curry syntax is a bit more obtuse, but not totally alien. For example: foo :: Int -> Int -> Int.
  • SML以易于理解的语法明确确认函数参数和返回类型。例如:val foo = fn:int * int - > int。 Haskell的隐式咖喱语法有点迟钝,但并非完全陌生。例如:foo :: Int - > Int - > Int。

SML has what you call "implicit curry" syntax as well.

SML也有你所谓的“隐式咖喱”语法。

$ sml
Standard ML of New Jersey v110.69 [built: Fri Mar 13 16:02:47 2009]
- fun add x y = x + y;
val add = fn : int -> int -> int

Essentially, SML and Haskell are roughly equivalent. I lean toward Haskell because I'm loving the list comprehensions and infinite lists in Haskell. But I'm worried that the extensive number of symbols in Haskell's compact syntax might cause students problems. From what I've gathered reading other posts on SO, Haskell is not recommended for beginners starting out with FP. But we're not going to be building full-fledged applications, just trying out simple algorithms.

从本质上讲,SML和Haskell大致相同。我倾向于Haskell,因为我喜欢Haskell中的列表理解和无限列表。但我担心Haskell紧凑语法中的大量符号可能会导致学生出现问题。从我收集到的关于SO的其他帖子开始,Haskell不建议初学者从FP开始。但我们不打算构建成熟的应用程序,只是尝试简单的算法。

I like using Haskell much more than SML, but I would still teach SML first.

我喜欢使用Haskell比SML更多,但我仍然会先教SML。

  • Seconding nominolo's thoughts, list comprehensions do seem to slow students from getting to some higher-order functions.
  • 借调nominolo的想法,列表推理确实会让学生放慢一些高阶函数的速度。

  • If you want laziness and infinite lists, it's instructive to implement it explicitly.
  • 如果你想要懒惰和无限列表,明确地实现它是有益的。

  • Because SML is eagerly evaluated, the execution model is far easier to comprehend, and "debugging via printf" works a lot better than in Haskell.
  • 因为热切地评估了SML,所以执行模型更容易理解,并且“通过printf调试”比Haskell更好地工作。

  • SML's type system is also simpler. While your class likely wouldn't use them anyways, Haskell's typeclasses are still an extra bump to get over -- getting them to understand the 'a versus ''a distinction in SML is tough enough.
  • SML的类型系统也更简单。虽然你的课程可能不会使用它们,但Haskell的类型类仍然是一个额外的碰撞 - 让他们理解“a对”在SML中的区别是非常困难的。

#6


Most answers were technical, but I think you should consider at least one that is not: Haskell (as OCaml), at this time, has a bigger community using it in a wider range of contexts. There's also a big database of libraries and applications written for profit and fun at Hackage. That may be an important factor in keeping some of your students using the language after your course is finished, and maybe trying other functional languages (like Standard ML) later.

大多数答案都是技术性的,但我认为你应该考虑至少一个不是:Haskell(作为OCaml),在这个时候,有一个更大的社区在更广泛的背景下使用它。还有一个庞大的图书馆和应用程序数据库,为Hackage的利润和乐趣而编写。这可能是让您的学生在课程结束后使用该语言的一个重要因素,也许可以在以后尝试其他功能语言(如标准ML)。

#7


I am amazed you are not considering OCaml and F# given that they address so many of your concerns. Surely decent and helpful development environments are a high priority for learners? SML is way behind and F# is way ahead of all other FPLs in that respect.

我很惊讶你不考虑OCaml和F#,因为它们解决了你的许多问题。当然,体面和有益的开发环境是学习者的首要任务吗?在这方面,SML远远落后于所有其他FPL。

Also, both OCaml and F# have list comprehensions.

此外,OCaml和F#都有列表推导。

#8


Haskell. I'm ahead in my algos/theory class in CS because of the stuff I learned from using Haskell. It's such a comprehensive language, and it will teach you a ton of CS, just by using it.

哈斯克尔。由于我从使用Haskell学到的东西,我在CS的算法/理论课中领先。它是如此全面的语言,只需使用它就可以教你大量的CS。

However, SML is much easier to learn. Haskell has features such as lazy evaluation and control structures that make it much more powerful, but with the cost of a steep(ish) learning curve. SML has no such curve.

但是,SML更容易学习。 Haskell具有惰性评估和控制结构等功能,使其功能更强大,但成本却是陡峭(ish)的学习曲线。 SML没有这样的曲线。

That said, most of Haskell was unlearning stuff from less scientific/mathematic languages such as Ruby, ObjC, or Python.

也就是说,Haskell的大部分内容都来自于较少科学/数学语言,如Ruby,ObjC或Python。