【发布时间】:2015-07-22 03:17:29
【问题描述】:
为了计算正方形和圆形的面积,我定义了以下类型:
type Square = {width: float; length: float;} with
member this.area = this.width * this.length
member this.perimeter = (this.width + this.length) * 2.
type Circle = {r:float} with
member this.area = System.Math.PI * this.r * this.r
member this.perimeter = 2. * System.Math.PI * this.r
let s1 = {width = 3.; length = 4.}
let c1 = {r = 8.3}
printfn "%A" s1
printfn "The area of s1 is: %A" s1.area
printfn "The perimeter of s1 is: %A" s1.perimeter
printfn "%A" c1
printfn "The area of c1 is: %A" c1.area
printfn "The perimeter of c1 is: %A" c1.perimeter
当我读到这篇文章时: http://fsharpforfunandprofit.com/posts/type-extensions/
它说:
- 方法不能很好地用于类型推断
- 方法不能很好地处理高阶函数
所以,恳请那些刚接触函数式编程的人。不要使用 如果可以的话,尤其是在你学习的时候。他们是 一个拐杖会阻止你从功能中获得全部好处 编程。
那么解决这个问题的函数式方法是什么?或者什么是惯用的 F# 方式?
编辑:
在阅读了“F# 组件设计指南”(对@V.B. 屈膝)和@JacquesB 的评论之后,我认为在类型中实现成员方法是最简单、内在的方式:
type Square2 (width: float, length: float) =
member this.area = width * length
member this.perimeter = (width + length) * 2.
(这与我原来的Square 类型几乎相同——这个Square2 只保存了几个this. 前缀,如this.width、this.length。)
同样,The F# Component Design Guidelines 非常有用。
【问题讨论】:
-
更多功能不一定更符合 F# 的习惯! F# 是一种面向对象/函数式的语言,适当地使用方法就可以了。当您已经了解 oo 时,这句话实际上是关于 学习 函数式编程,在这种情况下,尝试尽可能地函数式编程是一个很好的学习练习。
-
关于当前的两个答案以及反对“方法”的请求,当您预先了解所有案例时,请使用有区别的工会。这更实用,并且确实更好地映射了您的域——这 N 个选项是我唯一的案例——您将通过它了解更多 F#。当您希望能够通过您的程序临时定义新的实现时,请使用接口(和方法)。