基本的F#问题:可变性,资本化标准,功能与方法

时间:2009-05-29 05:59:33

标签: oop f# functional-programming naming-conventions mutable

如果已经提出要求,请随时给我指出其他答案!

我刚刚在本月的新版本中开始使用F#。我有OO和函数语言的一些背景知识(Haskell和Scheme,但不是OCaml / ML)。到目前为止,已经出现了几个问题,而不是阅读F#CTP附带的小教程。

1)可变变量是否优于monad?如果是这样,那么monad是否完全避免使用F#?

2)我对使用的大小写感到困惑。在本教程代码文件中,有时函数以小写字母开头,有时以大写字母开头。我知道MS倾向于喜欢带有函数和方法的初始大写,但在这里似乎有两种方法可以做到这一点。这对我来说并不是什么大不了的事,因为我只是在自己的时间玩耍,但我很好奇标准是什么。

3)我对OO和功能样式的整体组合感到非常困惑。 print_string "string"有意义,但接下来是List.map fn list(除非List只是命名空间,如果是这样,请原谅我)。那么这里是str.Length。任何人都在关心何时使用什么,哪个更受欢迎?

谢谢!

3 个答案:

答案 0 :(得分:5)

关于可变性:F#允许你务实。我很少喜欢状态monad到mutable / ref,但你可以做任何你喜欢的事情。 Monads并没有被回避,但我认为人们倾向于只在明确获胜时使用它们(例如异步编程)。

关于命名:“函数是值”意味着你可以选择用大写字母命名一个let-bound函数(因为它是一个函数,函数以大写字母开头)或者一个大写字母。 -case字母(因为它是一个let-bound值(恰好在其类型名称中有一个' - >'))。我个人更喜欢总是使用大写名称来表示所有函数,但是你会看到这两种风格(特别是因为F#库本身的风格在过去一两年里一直在慢慢演变/标准化)。在整个.Net中似乎都避开了下划线,并且F#库不再是一个例外(有一些名称留下使用下划线,但它们现在像拇指一样突出,可能会更改)。

关于功能风格:我不清楚你在问什么。对于List.map,“List”是F#模块的名称,“map”是该模块中的函数。成员函数(例如str.Length)具有在.Net中常用的优点,并在编辑器中提供良好的intellisense体验。

答案 1 :(得分:5)

1)我不会说monad被避开...你提到你有一些Haskell的背景 - 所以F#工作流是你想要研究的(术语工作流可能令人困惑但这些只有与业务流程的东西有点关系)。通常,序列表达式和更一般的计算表达式(a.k.a工作流程)将接近monad。虽然我不确定'首选'是表达它的方式,但是说可变性很常见。他们每个人都有一个地方 - 就个人而言,我从两本书开始 - “F#的基础” - 但如果你想潜入 - 去'专家F#' - 两者都很好。老实说,我需要基金会来帮助我开始。

2)在我的经历中,令人困惑的是,.NET中的传统函数有一个实际上不适用于函数式编程的约定。因此,我觉得在F#中,当你正在考虑使用'传统.NET'命名函数与F#中明显有用的元素时,你会感到困惑......例如,在我上面提到的那本书中'Expert F#' - 他们提到你会在camelCase和PascalCase中看到像List.map和Dates.Today这样的值(Pascal案例是更传统的.NET)。一个好的经验法则是,如果你留在功能世界 - 使用更传统的功能(camelCase)命名 - 但是如果你正在制作的东西预计将被其他.NET语言使用,那么请使用更多的.NET。规范(帕斯卡)。还要注意在功能世界中对缩写(itr,tbl等等)的容忍度要高得多,因为.NET通常已经远离这个...所以再次,你会看到不同程度的这个基于你是否在调用功能元素与在F#中公开的元素在整个.NET中共享的东西。

3)我同意OO和功能样式的组合可能会令人困惑。再说一次,我不确定哪个更受欢迎,除了说F#(功能性)在功能范例方面明确地表现出自己的风格。但是,F#是.NET世界中的一种函数式语言(请注意我上面提到的命名相对混乱)......再说一次,它并不是完全清晰的。

希望这有帮助...信不信由你,因为你使用F#并想到其他语言已经与C共享概念C ++(例如) - 它变得更容易。就个人而言,命名开始有意义并且概念起作用,因为我开始认为我是一个F#是一种在传统平台上运行的功能语言 - 用于互操作(尽管我不确定无缝的互操作是否合适: d)

答案 2 :(得分:2)

一般来说monad(F#中的“工作流程”)比Haskell中的要少得多,首先是因为可变变量可用,因此人们不太可能选择使用状态monad。其次,没有更高级的类型变量,这意味着你不能编写重载的代码来处理任何monad,这使得使用它们的吸引力更小。

它们常用的一个地方是序列表达式(这与Haskell中的列表推导非常相似,但它们与列表monad密切相关)。