idiomatic - Functional way to write these methods in F# -
in order calculate area of square , circle, defined following type:
type square = {width: float; length: float;} member this.area = this.width * this.length member this.perimeter = (this.width + this.length) * 2. type circle = {r:float} 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
when read article: http://fsharpforfunandprofit.com/posts/type-extensions/
it states:
- methods don't play type inference
- methods don't play higher order functions
so, plea of new functionally programming. don't use methods @ if can, when learning. crutch stop getting full benefit functional programming.
then what's functional way solve problem? or what's idomatic f# way?
edit:
after reading "the f# component design guidelines" (curtsy @v.b.), , @jacquesb's comment, consider implement member method within type simple, intrinsic way:
type square2 (width: float, length: float) = member this.area = width * length member this.perimeter = (width + length) * 2.
(this identical original square
type -- square2
saves seveal this.
prefix in this.width
, this.length
.)
again, the f# component design guidelines quite useful.
a more functional way create shape
discriminated union, square
, circle
cases. create functions area
, perimeter
, taking shape
, using pattern matching:
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)
Comments
Post a Comment