为了计算方形和圆形的面积,我定义了以下类型:
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
Run Code Online (Sandbox Code Playgroud)
当我读到这篇文章时:http: //fsharpforfunandprofit.com/posts/type-extensions/
它指出:
所以,请求那些刚接触功能编程的人.如果可以,请不要使用方法,特别是在学习时.它们是一个可以阻止您从函数式编程中获得全部好处的拐杖.
那么解决这个问题的功能方法是什么?或者F#方式是什么?
编辑:
在阅读了"F#组件设计指南"(屈膝于@VB)和@ JacquesB的评论之后,我认为在类型中实现成员方法是最简单的内在方式:
type Square2 (width: float, length: float) =
member this.area = width * length
member this.perimeter = (width + length) * 2.
Run Code Online (Sandbox Code Playgroud)
(这是我原来的几乎相同的Square类型-这Square2不仅节省了seveal this.作为前缀this.width,this.length.)
同样,F#组件设计指南非常有用.
一种更实用的方法是创建一个有Shape区别的联合,其中Square和Circle将是它的情况.然后创建函数area和perimeter,取Shape和使用模式匹配:
type Shape =
| Square of Width: float * Length: float
| Circle of R: float
let area = function
| Square (width, length) -> width * length
| Circle r -> System.Math.PI * r * r
let perimeter = function
| Square (width, length) -> (width + length) * 2.
| Circle r -> 2. * System.Math.PI * r
let s1 = Square(Width = 3., Length = 4.)
let c1 = Circle(R = 8.3)
printfn "%A" s1
printfn "The area of s1 is: %A" (area s1)
printfn "The perimeter of s1 is: %A" (perimeter s1)
printfn "%A" c1
printfn "The area of c1 is: %A" (area c1)
printfn "The perimeter of c1 is: %A" (perimeter c1)
Run Code Online (Sandbox Code Playgroud)