我对学习F#非常感兴趣。
我在函数式语言方面的唯一经验是在大学开设了两门关于Scheme的入门课程。
在学习F#时,我是否应该记住任何事情?方法,陷阱或其他可能给我带来麻烦的事情有何不同?
答案 0 :(得分:5)
在学习F#时,我是否应该记住任何事情?方法,陷阱或其他可能给我带来麻烦的事情有何不同?
静态类型是Scheme和F#之间的主要区别。这有助于称为类型编程的样式,其中类型系统用于编码关于函数和数据的约束,以便编译器在编译时证明程序的这些方面是正确的,并且立即捕获任何违反约束的行为
例如,可以通过以下类型的值传达一个或多个相同类型元素的序列:
type list1<'a> = List1 of 'a * 'a list
let xs = List1(1, [])
let ys = List1(2, [3; 4])
编译器现在保证在编译时将任何尝试使用这些序列中的空序列作为错误捕获。
现在,reduce
函数对空序列没有意义,因此内置实现在运行时列出barfs,如果遇到空序列则会出现异常:
> List.reduce (+) [];;
System.ArgumentException: The input list was empty.
Parameter name: list
at Microsoft.FSharp.Collections.ListModule.Reduce[T](FSharpFunc`2 reduction, FSharpList`1 list)
at <StartupCode$FSI_0271>.$FSI_0271.main@()
Stopped due to error
使用我们的一个或多个元素的新序列,我们现在可以编写一个reduce
函数,该函数在运行时从不barfs,但有异常,因为类型系统保证其输入非空:< / p>
let rec reduce f = function
| List1(x, []) -> x
| List1(x0, x1::xs) -> f x0 (reduce f (List1(x1, xs)))
这是一种通过消除运行时错误源来提高软件可靠性的好方法,而且像Scheme这样的动态类型语言甚至无法开始这样做。
答案 1 :(得分:3)
Scheme是一种很好的函数式语言;在学校学习它应该为函数式编程提供良好的基础。
F#是静态类型的,而Scheme是动态的,因此这是一个明显的区别。如果您有使用其他静态语言(尤其是像C#这样的.NET语言)的经验,那么这将不是什么大问题,但如果您的大部分经验都是动态的,那将是一个变化。
学习主要F#函数编程函数的名称(像List.map
这样的东西)很重要;大多数功能语言都具有相同的基本集,但通常具有不同的名称(我不记得要比较的主要Scheme名称。)
如果你有方便的示例输入/输出的旧'Scheme'编程作业',那么在F#中重新编码它们可能是有用的,可以用这种方式“热身”。
答案 2 :(得分:1)
我建议考虑Haskell,它们与F#和ML大致属于同一个家族,而Haskell包含许多其他地方没有的有趣的功能概念。
查看tryhaskell.org获取交互式在线教程。