Functional way to write these methods in F# - f#

In order to calculate the area of square and circle, I defined the following type:
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
When I read this article:
http://fsharpforfunandprofit.com/posts/type-extensions/
It states:
Methods don't play well with type inference
Methods don't play well with higher order functions
So, a plea for those of you new to functionally programming. Don't use
methods at all if you can, especially when you are learning. They are
a crutch that will stop you getting the full benefit from functional
programming.
Then what's the functional way to solve this problem? or what's the idomatic F# way?
Edit:
After reading the "The F# Component Design Guidelines" (curtsy to #V.B.), and #JacquesB's comment, I consider that implement the member method within the type is the most simple, intrinsic way:
type Square2 (width: float, length: float) =
member this.area = width * length
member this.perimeter = (width + length) * 2.
(This is almost identical with my original Square type -- this Square2 only saves seveal this. prefix as in this.width, this.length.)
Again, the The F# Component Design Guidelines is quite useful.

A more functional way to do this would be to create a Shape discriminated union, where Square and Circle would be its cases. Then create functions area and perimeter, taking Shape and 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)

There is a more functional way that #svick describes well, but consider also "The F# Component Design Guidelines"
Do use properties and methods for operations intrinsic to types.
This is called out specifically because some people from a functional
programming background avoid the use of object oriented programming
together, preferring a module containing a set of functions defining
the intrinsic functions related to a type (e.g. length foo rather than
foo.Length). But see also the next bullet. In general, in F#, the use
of object-oriented programming is preferred as a software engineering
device. This strategy also provides some tooling benefits such as
Visual Studio’s “Intellisense” feature to discover the methods on a
type by “dotting into” an object.
Consider using interface types to represent related groups of operations that may be implemented in multiple ways.
In F# there are a number of ways to represent a dictionary of
operations, such as using tuples of functions or records of functions.
In general, we recommend you use interface types for this purpose.
So, according to these guidelines, an interface IShape with Area and Perimeter members is a recommended way for an F# component, despite there is a "more functional" way in general.

Related

Function return tuple and the result is assigned to new variables

I've just started learning F# very recently. I have a function which counts the coefficients of the linear equation: y = ax + b, based on coordinates of two points P1(x1, y1), P2(x1, y2). The function looks like this:
module LinearFit
let generate(x1 : double, y1 : double, x2 : double, y2 : double) =
let w = x1 * 1.0 - x2 * 1.0
let wa = y1 * 1.0 - y2 * 1.0
let wb = x1 * y2 - x2 * y1
printfn "w: %g" w
printfn "wa: %g" wa
printfn "wb: %g" wb
let a = wa/w
let b = wb/w
printfn "a: %g" a
printfn "b: %g" b
printfn "%g %g" a b
(a, b)
I'm trying to somehow return founded coefficients as a tuple result and then assign the result to the new variables so later I can use the result to do some other operations. The trivial thing, for now, would be just displayed a result like:
The generated function is y = 2.5x - 6.5
So far I was trying to do sth like this
open System
let main() =
printf "Linear fit"
(a: double, b: double) <- LinearFit.generate(5.0, 6.0, 7.0, 11.0)
printfn "The generated functi..."
main()
Console.ReadKey() |> ignore
This is only a concept as I'm not even able to compile the project as im getting errors:
"Unexpected symbol ',' in expression"
"Unexpected symbol ')' in binding."
I tried to find some similar approach to C#...
For now what I want to achieve is just to assing the result of generate function to some variables. In C# it would look just like
public (double a, double b) Generate(some params here)
{
// some logic here
return (a, b);
}
(var a, var b) = Generate(...);
Any ideas?
You're making several syntactic mistakes.
First, the arrow-left operator <- is destructive update. It takes a mutable variable on the right and an expression on the left, and pushes the value of the expression into the variable. For example:
let mutable x = 5
x <- 42
In your example, neither a nor b are mutable variables that exist by the time you're trying to use the <- operator. Plus, the operator expects a single mutable variable, not a pattern.
Second, the way to declare new variables in F# is with let. It is roughly equivalent to var in C#, except you can declare multiple variables at once by putting them in a pattern. For example:
let x = 42
let pair = (1, 5)
let a, b = pair
Here, on the last line, I'm declaring two variables a and b by destructuring the pair.
In your example, you're trying to introduce the two new variables a and b without a let keyword. This is not allowed.
So, putting all of the above together, this is the right way to do what you're trying to do:
let main() =
printf "Linear fit"
let a, b = LinearFit.generate(5.0, 6.0, 7.0, 11.0)
printfn "The generated functi..."
P.S. Your question betrays a misunderstanding of some pretty basic principles of F# syntax. Because of this, I would recommend that you read through tutorials, examples, and other articles on F# to familiarize yourself with the syntax before attempting to venture farther.

Proper F# type annotation for MathNet.Numerics.LinearAlgebra.vector

I have the following program:
open System
open MathNet.Numerics
open MathNet.Numerics.LinearAlgebra
//entropy
let entropy v =
let pct = v / v.Sum()
let l1 = pct.Map (fun x -> System.Math.Log(x, 2.0))
let p = Vector.map2 (fun x y -> x * y) pct l1
let e = - p.Sum()
e
[<EntryPoint>]
let main argv =
let v1 = vector [ 1.0 ; 3.0 ; 5.0 ]
let e1 = entropy v1
0 // return an integer exit code
I need to provide a type annotation for the varable v in the entropy function. As you can see, the parameter I am passing to the function (v1) is defined as MathNet.Numerics.LinearAlgebra.vector. I have tried lots of options for the type annotation without success.
What should it be? Bonus points if you can help me understand how you came up with your answer.
This vector type is generic; the generic argument indicates the type of each component of the vector. A type annotation must at least indicate the number of generic arguments, e.g. Vector<_> for any such vector, or Vector<float> for the exact type used in the question.
In other words, Vector<_> and Vector are unrelated types to the compiler. The annotation is supposed to denote the type Vector with one, not zero generic arguments.
I would expect the "rough" annotation (v : Vector<_>) to suffice; the compiler would then infer the generic argument from the use of a float -- the value 2.0 -- later in the function. I don't use the library though, so I didn't test this.

What's the meaning of the `in` keyword in this example (F#)

I've been trying to get my head round various bits of F# (I'm coming from more of a C# background), and parsers interest me, so I jumped at this blog post about F# parser combinators:
http://santialbo.com/blog/2013/03/24/introduction-to-parser-combinators
One of the samples here was this:
/// If the stream starts with c, returns Success, otherwise returns Failure
let CharParser (c: char) : Parser<char> =
let p stream =
match stream with
| x::xs when x = c -> Success(x, xs)
| _ -> Failure
in p //what does this mean?
However, one of the things that confused me about this code was the in p statement. I looked up the in keyword in the MSDN docs:
http://msdn.microsoft.com/en-us/library/dd233249.aspx
I also spotted this earlier question:
Meaning of keyword "in" in F#
Neither of those seemed to be the same usage. The only thing that seems to fit is that this is a pipelining construct.
The let x = ... in expr allows you to declare a binding for some variable x which can then be used in expr.
In this case p is a function which takes an argument stream and then returns either Success or Failure depending on the result of the match, and this function is returned by the CharParser function.
The F# light syntax automatically nests let .. in bindings, so for example
let x = 1
let y = x + 2
y * z
is the same as
let x = 1 in
let y = x + 2 in
y * z
Therefore, the in is not needed here and the function could have been written simply as
let CharParser (c: char) : Parser<char> =
let p stream =
match stream with
| x::xs when x = c -> Success(x, xs)
| _ -> Failure
p
The answer from Lee explains the problem. In F#, the in keyword is heritage from earlier functional languages that inspired F# and required it - namely from ML and OCaml.
It might be worth adding that there is just one situation in F# where you still need in - that is, when you want to write let followed by an expression on a single line. For example:
let a = 10
if (let x = a * a in x = 100) then printfn "Ok"
This is a bit funky coding style and I would not normally use it, but you do need in if you want to write it like this. You can always split that to multiple lines though:
let a = 10
if ( let x = a * a
x = 100 ) then printfn "Ok"

Storing multidimensional points in F#

I am currently porting some code from Java to F# that deals with multidimensional functions. It supports variable dimension, so in the original implementation each point is represented as an array of doubles. The critical function of the code is an optimisation routine, that basically generates a sequence of points based on some criteria, evaluates a given function at these points and looks for a maximum. This works for any dimension. The operations I need are:
check the dimension of a point
create a new point with the same dimension of a given point
set (in procedural or functional sense) a given coordinate of a point
In F# I could obviously also use arrays in the same way. I was wandering though if there is a better way. If the dimension was fixed in advance, the obvious choice would be to use tuples. Is it possible to use tuples in this dynamic setting though?
No, tuples will be fixed by dimension. Also note that .NET tuples are boxed. If you are operating on large collections of points with small dimension (such as arrays of 2d points), using structs may help.
If you really want to push the F#/.NET advantage over Java, have a look at generics. Writing code with generics allows to write code that works for any dimension, and use different representations for different dimensions (say structs for 1-3 dimensions, and vectors for larger dimensions):
let op<'T where 'T :> IVector> (x: 'T) =
...
This is only relevant though if you are willing to go a long way to get the absolutely best performance and generality. Most projects do not need that, stick with the simplest thing that works.
For the fun of it, here is an extended example of how to utilize generics and F# inlining:
open System.Numerics
type IVector<'T,'V> =
abstract member Item : int -> 'T with get
abstract member Length : int
abstract member Update : int * 'T -> 'V
let lift<'T,'V when 'V :> IVector<'T,'V>> f (v: 'V) : 'V =
if v.Length = 0 then v else
let mutable r = v.Update(0, f v.[0])
for i in 1 .. v.Length - 1 do
r <- r.Update(i, f v.[i])
r
let inline norm (v: IVector<_,_>) =
let sq i =
let x = v.[i]
x * x
Seq.sum (Seq.init v.Length sq)
let inline normalize (v: 'V) : 'V =
let n = norm v
lift (fun x -> x / n) v
[<Struct>]
type Vector2D<'T>(x: 'T, y: 'T) =
member this.X = x
member this.Y = y
interface IVector<'T,Vector2D<'T>> with
member this.Item
with get (i: int) =
match i with
| 0 -> x
| _ -> y
member this.Length = 2
member this.Update(i: int, v: 'T) =
match i with
| 0 -> Vector2D(v, y)
| _ -> Vector2D(x, v)
override this.ToString() =
System.String.Format("{0}, {1}", x, y)
[<Sealed>]
type Vector<'T>(x: 'T []) =
interface IVector<'T,Vector<'T>> with
member this.Item with get (i: int) = x.[i]
member this.Length = x.Length
member this.Update(i: int, v: 'T) =
let a = Array.copy x
a.[i] <- v
Vector(a)
override this.ToString() =
x
|> Seq.map (fun e -> e.ToString())
|> String.concat ", "
[<Struct>]
type C(c: Complex) =
member this.Complex = c
static member Zero = C(Complex(0., 0.))
static member ( + ) (a: C, b: C) = C(a.Complex + b.Complex)
static member ( * ) (a: C, b: C) = C(a.Complex * b.Complex)
static member ( / ) (a: C, b: C) = C(a.Complex / b.Complex)
override this.ToString() = string c
let v1 = Vector2D(10., 30.)
normalize v1
|> printfn "%O"
let v2 = Vector2D(C(Complex(1.25, 0.8)), C(Complex(0.5, -1.)))
normalize v2
|> printfn "%O"
let v3 = Vector([| 10.; 30.; 50.|])
normalize v3
|> printfn "%O"
Note that norm and normalize are fairly general, they cope with specialized 2D vectors and generalized N-dimensional vectors, and with different component types such as complex numbers (you can define your own). The use of generics and F# inlining ensure that while general, these algorithms perform well for the special cases, using compact representations. This is where F# and .NET generics shine compared to Java, where you are obliged to create specialized copies of your code to get decent performance.

F# Power issues which accepts both arguments to be bigints

I am currently experimenting with F#. The articles found on the internet are helpful, but as a C# programmer, I sometimes run into situations where I thought my solution would help, but it did not or just partially helped.
So my lack of knowledge of F# (and most likely, how the compiler works) is probably the reason why I am totally flabbergasted sometimes.
For example, I wrote a C# program to determine perfect numbers. It uses the known form of Euclids proof, that a perfect number can be formed from a Mersenne Prime 2p−1(2p−1) (where 2p-1 is a prime, and p is denoted as the power of).
Since the help of F# states that '**' can be used to calculate a power, but uses floating points, I tried to create a simple function with a bitshift operator (<<<) (note that I've edit this code for pointing out the need):
let PowBitShift (y:int32) = 1 <<< y;;
However, when running a test, and looking for performance improvements, I also tried a form which I remember from using Miranda (a functional programming language also), which uses recursion and a pattern matcher to calculate the power. The main benefit is that I can use the variable y as a 64-bit Integer, which is not possible with the standard bitshift operator.
let rec Pow (x : int64) (y : int64) =
match y with
| 0L -> 1L
| y -> x * Pow x (y - 1L);;
It turns out that this function is actually faster, but I cannot (yet) understand the reason why. Perhaps it is a less intellectual question, but I am still curious.
The seconds question then would be, that when calculating perfect numbers, you run into the fact that the int64 cannot display the big numbers crossing after finding the 9th perfectnumber (which is formed from the power of 31). I am trying to find out if you can use the BigInteger object (or bigint type) then, but here my knowledge of F# is blocking me a bit. Is it possible to create a powerfunction which accepts both arguments to be bigints?
I currently have this:
let rec PowBigInt (x : bigint) (y : bigint) =
match y with
| bigint.Zero -> 1I
| y -> x * Pow x (y - 1I);;
But it throws an error that bigint.Zero is not defined. So I am doing something wrong there as well. 0I is not accepted as a replacement, since it gives this error:
Non-primitive numeric literal constants cannot be used in pattern matches because they
can be mapped to multiple different types through the use of a NumericLiteral module.
Consider using replacing with a variable, and use 'when <variable> = <constant>' at the
end of the match clause.
But a pattern matcher cannot use a 'when' statement. Is there another solution to do this?
Thanks in advance, and please forgive my long post. I am only trying to express my 'challenges' as clear as I can.
I failed to understand why you need y to be an int64 or a bigint. According to this link, the biggest known Mersenne number is the one with p = 43112609, where p is indeed inside the range of int.
Having y as an integer, you can use the standard operator pown : ^T -> int -> ^T instead because:
let Pow (x : int64) y = pown x y
let PowBigInt (x: bigint) y = pown x y
Regarding your question of pattern matching bigint, the error message indicates quite clearly that you can use pattern matching via when guards:
let rec PowBigInt x y =
match y with
| _ when y = 0I -> 1I
| _ -> x * PowBigInt x (y - 1I)
I think the easiest way to define PowBigInt is to use if instead of pattern matching:
let rec PowBigInt (x : bigint) (y : bigint) =
if y = 0I then 1I
else x * PowBigInt x (y - 1I)
The problem is that bigint.Zero is a static property that returns the value, but patterns can only contain (constant) literals or F# active patterns. They can't directly contain property (or other) calls. However, you can write additional constraints in where clause if you still prefer match:
let rec PowBigInt (x : bigint) (y : bigint) =
match y with
| y when y = bigint.Zero -> 1I
| y -> x * PowBigInt x (y - 1I)
As a side-note, you can probably make the function more efficent using tail-recursion (the idea is that if a function makes recursive call as the last thing, then it can be compiled more efficiently):
let PowBigInt (x : bigint) (y : bigint) =
// Recursive helper function that stores the result calculated so far
// in 'acc' and recursively loops until 'y = 0I'
let rec PowBigIntHelper (y : bigint) (acc : bigint) =
if y = 0I then acc
else PowBigIntHelper (y - 1I) (x * acc)
// Start with the given value of 'y' and '1I' as the result so far
PowBigIntHelper y 1I
Regarding the PowBitShift function - I'm not sure why it is slower, but it definitely doesn't do what you need. Using bit shifting to implement power only works when the base is 2.
You don't need to create the Pow function.
The (**) operator has an overload for bigint -> int -> bigint.
Only the second parameter should be an integer, but I don't think that's a problem for your case.
Just try
bigint 10 ** 32 ;;
val it : System.Numerics.BigInteger =
100000000000000000000000000000000 {IsEven = true;
IsOne = false;
IsPowerOfTwo = false;
IsZero = false;
Sign = 1;}
Another option is to inline your function so it works with all numeric types (that support the required operators: (*), (-), get_One, and get_Zero).
let rec inline PowBigInt (x:^a) (y:^a) : ^a =
let zero = LanguagePrimitives.GenericZero
let one = LanguagePrimitives.GenericOne
if y = zero then one
else x * PowBigInt x (y - one)
let x = PowBigInt 10 32 //int
let y = PowBigInt 10I 32I //bigint
let z = PowBigInt 10.0 32.0 //float
I'd probably recommend making it tail-recursive, as Tomas suggested.

Resources