Bar*_*own 76 haskell functional-programming sml discrete-mathematics
我将在离散结构中教授低级课程.我选择了教科书" 离散结构,逻辑和可计算性",因为它包含有助于使用函数式编程语言实现的示例和概念.(我也认为这是一本很好的教科书.)
我想要一个易于理解的FP语言来说明DS概念以及学生可以使用的.大多数学生最多只能用一到两个学期的Java编程.在查看Scheme,Erlang,Haskell,Ocaml和SML之后,我已经确定了Haskell或Standard ML.由于下面列出的原因,我倾向于Haskell,但我喜欢那些活跃的程序员在一个或另一个的意见.
从本质上讲,SML和Haskell大致相同.我倾向于Haskell,因为我喜欢Haskell中的列表理解和无限列表.但我担心Haskell紧凑语法中的大量符号可能会导致学生出现问题.从我收集到的关于SO的其他帖子开始,Haskell不建议初学者从FP开始.但我们不打算构建成熟的应用程序,只是尝试简单的算法.
你怎么看?
编辑:在阅读了一些很棒的回复后,我应该澄清一些我的要点.
在SML中,在解释器中定义函数和在外部文件中定义函数之间没有语法上的区别.假设您要编写阶乘函数.在Haskell中,您可以将此定义放入文件中并将其加载到GHCi中:
fac 0 = 1
fac n = n * fac (n-1)
Run Code Online (Sandbox Code Playgroud)
对我来说,这很清楚,简洁,并且符合书中的数学定义.但是如果你想直接在GHCi中编写函数,你必须使用不同的语法:
let fac 0 = 1; fac n = n * fac (n-1)
Run Code Online (Sandbox Code Playgroud)
在使用交互式口译员时,从教学角度来看,当学生在文件和命令行中使用相同的代码时,非常非常方便.
通过"显式确认函数",我的意思是在定义函数时,SML立即告诉您函数的名称,参数的类型和返回类型.在Haskell中你必须使用:type命令,然后你会得到一些有点令人困惑的咖喱符号.
关于Haskell的一个更酷的事情 - 这是一个有效的函数定义:
fac 0 = 1
fac (n+1) = (n+1) * fac n
Run Code Online (Sandbox Code Playgroud)
同样,这与他们可能在教科书中找到的定义相匹配.在SML中无法做到这一点!
Nor*_*sey 86
就像我喜欢Haskell一样,以下是我更喜欢SML用于离散数学和数据结构(以及大多数其他初学者类)的类的原因:
即使对于专家来说,Haskell程序的时间和空间成本也很难预测.SML提供了更有限的方式来吹制机器.
交互式解释器中的函数定义语法与文件中使用的语法相同,因此您可以剪切和粘贴.
虽然SML中的运算符重载完全是假的,但它也很简单.在不必进入类型类的情况下,很难在Haskell中教授整个类.
学生可以使用调试print.(虽然,正如评论者指出的那样,在Haskell中使用它可能会得到几乎相同的效果Debug.Trace.trace.)
无限的数据结构打动了人们的思想.对于初学者来说,最好让他们定义一个带有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
Run Code Online (Sandbox Code Playgroud)
现在它不再是魔术了,你可以从这里到流(无限列表).
布局不像Python那么简单,可能会令人困惑.
Haskell有两个优势:
在核心Haskell中,您可以在定义之前编写函数的类型签名.这对学生和其他初学者非常有帮助.在SML中处理类型签名并不是一种好方法.
Haskell具有更好的具体语法.Haskell语法是对ML语法的重大改进.我写了一篇关于何时在ML程序中使用括号的简短说明 ; 这有点帮助.
最后,有一把剑可以削减两种方式:
do符号,并且return令人困惑.在相关主题上,这里有一些关于课程准备的建议:不要忽视Chris Okasaki的Purely Functional Data Structures.即使你没有让你的学生使用它,你一定会想要一份副本.
nom*_*olo 29
我们在大学的第一年教Haskell.我对此的看法有点混乱.一方面教Haskell到第一年意味着他们不必忘记命令式的风格.Haskell也可以生成非常简洁的代码,以前有过Java的人可以欣赏它们.
我注意到学生经常遇到的一些问题:
首先,模式匹配可能有点困难.学生最初在看到价值构建和模式匹配是如何相关时遇到了一些问题.他们在区分抽象方面也存在一些问题.我们的练习包括编写简化算术表达的函数,有些学生很难看到抽象表示(例如Const 1)和元语言表示(1)之间的区别.
此外,如果您的学生应该自己编写列表处理功能,请注意指出模式之间的差异
[]
[x]
(x:xs)
[x:xs]
Run Code Online (Sandbox Code Playgroud)
根据您想要在途中教授多少函数式编程,您可以给它们一些库函数,让它们随意使用它们.
我们没有教我们的学生匿名功能,我们只是告诉他们有关where条款.对于某些任务,这有点冗长,但其他方面效果不错.我们也没有告诉他们部分申请; 这可能很容易在Haskell中解释(由于它的编写类型),所以它可能值得向他们展示.
他们很快就发现列表理解和首选他们在高阶功能,如filter,map,zipWith.
我想我们错过了教他们如何让他们按类型引导他们的想法.不过,我不太确定这对初学者是否有帮助.
错误消息通常对初学者没有太大帮助,他们可能偶尔需要一些帮助.我自己没有尝试过,但是有一个专门针对新手的Haskell编译器,主要是通过更好的错误消息:Helium
对于小型程序,可能的空间泄漏等问题不是问题.
总的来说,Haskell是一种很好的教学语言,但有一些陷阱.鉴于学生对列表推导感觉比高阶函数更舒服,这可能是您需要的论据.我不知道你的课程有多长,或者你想教他们多少程序,但是要花些时间教他们基本概念 - 他们需要它.
Don*_*art 13
顺便说一句,
#SML有一个真正的交互式解释器,可以在其中定义和使用函数.在Haskell中,函数必须在单独的文件中定义,并在交互式shell中使用之前进行编译.
不准确.使用GHCi:
Prelude> let f x = x ^ 2
Prelude> f 7
49
Prelude> f 2
4
Run Code Online (Sandbox Code Playgroud)
在haskell.org edu上,Haskell在教育方面也有很好的资源.页面,有不同老师的经验.http://haskell.org/haskellwiki/Haskell_in_education
最后,如果你使用Haskell,你将能够教他们多核并行,只是为了好玩:-)
GS *_*ica 11
许多大学教Haskell作为第一种功能语言甚至是第一种编程语言,所以我认为这不会是一个问题.
在一门这样的课程上完成了一些教学,我不同意你认识到的可能的混淆.早期混淆的最可能的来源是解析由错误布局引起的错误,以及在错误地使用数字文字时关于类型类的神秘消息.
我也不同意任何关于Haskell不建议初学者开始使用FP的建议.对于突变的严格语言来说,这肯定是一个大爆炸的方法,但我认为这是一种非常有效的方法.
- SML有一个真正的交互式解释器,可以在其中定义和使用函数.在Haskell中,函数必须在单独的文件中定义,并在交互式shell中使用之前进行编译.
虽然拥抱可能有这种限制,但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"
Run Code Online (Sandbox Code Playgroud)
我喜欢GHC(i)而不是Hugs的原因有很多,这只是其中之一.
- SML以易于理解的语法明确确认函数参数和返回类型.例如:val foo = fn:int*int - > int.Haskell隐含的咖喱语法有点迟钝,但并非完全陌生.例如:foo :: Int - > Int - > Int.
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
Run Code Online (Sandbox Code Playgroud)
从本质上讲,SML和Haskell大致相同.我倾向于Haskell,因为我喜欢Haskell中的列表理解和无限列表.但我担心Haskell紧凑语法中的大量符号可能会导致学生出现问题.从我收集到的关于SO的其他帖子开始,Haskell不建议初学者从FP开始.但我们不打算构建成熟的应用程序,只是尝试简单的算法.
我喜欢使用Haskell比SML更多,但我仍然会先教SML.
'a与''a在SML的区别是不够强硬.我很惊讶您没有考虑 OCaml 和 F#,因为它们解决了您的许多问题。体面和有用的开发环境肯定是学习者的重中之重吗?SML 远远落后,而 F# 在这方面领先于所有其他 FPL。
此外,OCaml 和 F# 都有列表推导式。
哈斯克尔。由于我从使用 Haskell 中学到的东西,我在计算机科学的算法/理论课上取得了领先。这是一门非常全面的语言,只要使用它,它就能教你大量的计算机科学知识。
然而,SML 更容易学习。Haskell 具有惰性求值和控制结构等功能,使其更加强大,但代价是学习曲线陡峭。SML没有这样的曲线。
也就是说,大多数 Haskell 都放弃了从 Ruby、ObjC 或 Python 等不太科学/数学的语言中学习的东西。