纯函数式编程使用 F#

15

是否有可能强制F#表现得像纯函数式语言Haskell一样?也许使用一些编译器指令?

附注:由于我来自C/C++背景,我想在不学习Haskell的情况下强迫自己学习函数式编程 :)


8
为什么不学习Haskell呢?它的语法几乎是F#的子集,如果有Haskell的知识,学习F#将轻松许多。可能的副作用是你会讨厌F#。 - luqui
5个回答

14

在 F# 中,你无法强制执行这种行为,但正如 Brian 所说,约束是你最好的朋友。例如,不要使用 mutablefor 或者 while 循环,ref 关键字等。同时,使用纯不可变数据结构(discriminated union、list、tuple、map 等)。如果你需要进行 IO 操作,在架构程序时将其与纯函数式代码分离。

别忘了,函数式编程是关于限制和隔离副作用的。


4
不要忘记,函数式编程的重点是限制和隔离副作用 - 或者表示它们,使它们不再是“副作用” :) - mokus
1
不要忘记,函数式编程的核心是限制和隔离副作用。对我来说,它也涉及正确定义类型,使得无效状态变得不可表示。虽然在其他语言(如C++)中也可以实现这一点,但F#和其他函数式语言的类型系统使其更加容易。 - sashang

10

不好意思,你只能靠自律。


你能做到吗?你必须为通常具有副作用(如I/O)的所有操作创建单子。 - Gabe
1
@Gabe:除了Haskell的单子系统之外,还有其他的IO模型,尽管这是我听说过的灵活性和简单性之间最好的权衡。如果你想阅读一些非常深入的关于这个主题的推理,你可能会对Simon Peyton Jones的“尴尬小队”论文感兴趣。 - Chuck
Chuck:你是说F#有一个纯函数式的I/O原语,它不是单子吗?还是说,你实现I/O所需的任何内容都不必是单子? - Gabe
1
F#没有纯函数式I/O原语——它使用有副作用的函数和按值调用。是的,除了monad之外,还有其他纯函数式IO的方法。看看awkward squad paper吧。 - luqui

4
如果你和我一样,如果不强制自己使用Haskell并尽可能地以惯用法使用Haskell,你可能会避开“好东西”。使用代数数据类型而不是对象,学习喜欢惰性,拥抱单子等更多是Haskell的核心部分,也是纯函数编程的一些细节(在我看来)。
在许多方面上,F#的学习曲线没有那么陡峭,但你似乎正在为了兴趣而学习它,那么为什么不挑战自己呢?我可以证明,在使用Haskell后转向F#可以让你更好地感受到如何以一般方式使用F#。
思考食物。

2
Haskell的纯函数方面是该语言的基础,不能简单地将其移植到其他语言中。这导致了重大的设计决策,例如Haskell的纯函数特性导致了IO monad的发明。F#没有这样的“逃逸阀”来处理有状态计算。
此外,在支持函数式编程但不绝对强制执行的语言中学习编程实际上可能是有益的。许多人会混淆Haskell的个别设计决策(例如IO monad,再举一个大例子)和函数式编程的工作原理。
总之:不行,但你可以非常仔细地观察并质疑涉及维护状态和排序操作的所有操作,以确保没有更纯净的抽象形式被忽略。

0

不可以。目前F#编译器无法进行此类检查。

为什么不开始写一些F#程序来学习函数式编程呢?我认识一些人先学习ML/Ocaml/F#然后再转移到Haskell。

这样你就会更好地理解纯度。(如果您以前没有接触过任何函数式编程语言,那么您对纯函数式的理解可能是肤浅的。)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接