Is there default parameter in F#? - f#

I wrote a program to convert file size from bytes to a human readable format in F#:
let rec sizeFmt num i =
let suffix="B"
let unit = ["";"Ki";"Mi";"Gi";"Ti";"Pi";"Ei";"Zi"]
match abs num with
| x when x < 1024.0 -> printfn "%3.1f %s%s" num unit.[i] suffix
| _ -> sizeFmt (num / 1024.0) (i+1)
let humanReadable n =
sizeFmt (float n) 0
Run example:
> humanReadable 33;;
33.0 B
val it : unit = ()
> humanReadable 323379443;;
308.4 MiB
val it : unit = ()
>
Question:
It would be nice if I can set i=0 as the default value in the
sizeFmt funciton. I checked the F# documentation, only found that
there's no default parameter. So I have to write a wrapper function
humanReadable. Is there a better way?
In order to handle both int and float type input like humanReadable 123;; and humanReadable 123433.33;;, I have to add a float n in the wrapper function. The obvious problem is: it is very easy to exceed the max int size which is 2,147,483,647. I guess there might be a better way, are there?

If sizeFmt is only used by humanReadable, it makes sense to make it an inner function. That avoids the 'parameter default' issue.
Also, marking the outer function inline causes it to accept any type of n that supports explicit conversion to float.
let inline humanReadable n =
let rec sizeFmt num i =
let suffix="B"
let unit = ["";"Ki";"Mi";"Gi";"Ti";"Pi";"Ei";"Zi"]
match abs num with
| x when x < 1024.0 -> printfn "%3.1f %s%s" num unit.[i] suffix
| _ -> sizeFmt (num / 1024.0) (i+1)
sizeFmt (float n) 0
humanReadable 123 //works
humanReadable 123433.33 //also works

One F# convention that may help is to put primary parameters at the end of the parameter list and secondary parameters first - the opposite of the convention in OO languages. This lets you pipe your primary argument to your function, e.g.
let rec sizeFmt i num =
...
123.0 |> sizeFmt 0
It also lets you easily create partial functions with optional parameters filled in:
let humanReadable = sizeFmt 0
In answer to 2, no there is no better way, unless you make sizeFmt generic and pass in the typed value of 1024.0 but this probably won't make it any simpler.

The only way to have an optional parameter in F# is to use a method instead of a function. To specify that a parameter is optional, put a ? before it. From the documentation here:
type DuplexType =
| Full
| Half
type Connection(?rate0 : int, ?duplex0 : DuplexType, ?parity0 : bool) =
let duplex = defaultArg duplex0 Full
let parity = defaultArg parity0 false
let mutable rate = match rate0 with
| Some rate1 -> rate1
| None -> match duplex with
| Full -> 9600
| Half -> 4800
do printfn "Baud Rate: %d Duplex: %A Parity: %b" rate duplex parity
let conn1 = Connection(duplex0 = Full)
let conn2 = Connection(duplex0 = Half)
let conn3 = Connection(300, Half, true)

Although I know that's not what is being asked about, did you know about F#'s Units of Measure feature?
[<Measure>] type B
[<Measure>] type kB
let bPerKB = 1024.M<B/kB>
let bytesToKiloBytes (bytes : decimal<B>) = bytes / bPerKB
let kiloBytesToBytes (kiloBytes : decimal<kB>) = kiloBytes * bPerKB
This gives you a type-safe way to distinguish bytes from kilobytes, and prevents you from accidentally assigning a kilobyte value to a function that expects bytes.
Here are some example conversions:
> 1024.M<B> |> bytesToKiloBytes;;
val it : decimal<kB> = 1M
> 1145.M<B> |> bytesToKiloBytes;;
val it : decimal<kB> = 1.1181640625M
> 1.M<kB> |> kiloBytesToBytes;;
val it : decimal<B> = 1024M
If you just need the function like above as a quick way to make a large byte value human-readable, this is surely overkill, but if you need to manage byte values on many scales, this may be appropriate.

The existing answers already explain that keeping a wrapper function is a good idea, since this lets the code be as much modular as possible. This would not be very obvious in a simple example, but in real-life projects it would be a great advantage to be able to extend sizeFmt at some moment by exposing more parameters ā€” consider that you may occasionally need "Hertz" instead of "Bytes" (and division by 1000 instead of 1024), or a sting format pattern (five decimal digits), or a localizable list of multipliers, and so on.
As for the second question, converting to float, the solution is very simple: make value a statically-resolved type:
let inline humanReadable (value:^T) =
sizeFmt (float value) 0
This will make humanReadable to have the following type constraint:
val inline humanReadable :
value: ^T -> unit when ^T : (static member op_Explicit : ^T -> float)
Usage:
humanReadable 42424242.42 // float
humanReadable 4242 // int
humanReadable 42424242424242424242I // Numerics.BigInteger
humanReadable (424242424242424242422424N / 5N) // BigRational
Using float in the inner function seems to be fine: any round-off errors will be eliminated by a series of divisions.

Related

How extract the int from a FsCheck.Gen.choose

I'm new on F#, and can't see how extract the int value from:
let autoInc = FsCheck.Gen.choose(1,999)
The compiler say the type is Gen<int>, but can't get the int from it!. I need to convert it to decimal, and both types are not compatible.
From a consumer's point of view, you can use the Gen.sample combinator which, given a generator (e.g. Gen.choose), gives you back some example values.
The signature of Gen.sample is:
val sample : size:int -> n:int -> gn:Gen<'a> -> 'a list
(* `size` is the size of generated test data
`n` is the number of samples to be returned
`gn` is the generator (e.g. `Gen.choose` in this case) *)
You can ignore size because Gen.choose ignores it, as its distribution is uniform, and do something like:
let result = Gen.choose(1,999) |> Gen.sample 0 1 |> Seq.exactlyOne |> decimal
(* 0 is the `size` (gets ignored by Gen.choose)
1 is the number of samples to be returned *)
The result should be a value in the closed interval [1, 999], e.g. 897.
Hi to add to what Nikos already told you, this is how you can get an decimal between 1 and 999:
#r "FsCheck.dll"
open FsCheck
let decimalBetween1and999 : Gen<decimal> =
Arb.generate |> Gen.suchThat (fun d -> d >= 1.0m && d <= 999.0m)
let sample () =
decimalBetween1and999
|> Gen.sample 0 1
|> List.head
you can now just use sample () to get a random decimal back.
In case you just want integers between 1 and 999 but have those converted to decimal you can just do:
let decimalIntBetween1and999 : Gen<decimal> =
Gen.choose (1,999)
|> Gen.map decimal
let sampleInt () =
decimalIntBetween1and999
|> Gen.sample 0 1
|> List.head
what you probably really want to do instead
Is use this to write you some nice types and check properties like this (here using Xunit as a test-framework and the FsCheck.Xunit package:
open FsCheck
open FsCheck.Xunit
type DecTo999 = DecTo999 of decimal
type Generators =
static member DecTo999 =
{ new Arbitrary<DecTo999>() with
override __.Generator =
Arb.generate
|> Gen.suchThat (fun d -> d >= 1.0m && d <= 999.0m)
|> Gen.map DecTo999
}
[<Arbitrary(typeof<Generators>)>]
module Tests =
type Marker = class end
[<Property>]
let ``example property`` (DecTo999 d) =
d > 1.0m
Gen<'a> is a type that essentially abstracts a function int -> 'a (the actual type is a bit more complex, but let's ignore for now). This function is pure, i.e. when given the same int, you'll get the same instance of 'a back every time. The idea is that FsCheck generates a bunch of random ints, feeds them to the Gen function, out come random instances of the type 'a you're interested in, and feeds those to a test.
So you can't really get out the int. You have in your hands a function that given an int, generates another int.
Gen.sample as described in another answer essentially just feeds a sequence of random ints to the function and applies it to each, returning the results.
The fact that this function is pure is important because it guarantees reproducibility: if FsCheck finds a value for which a test fails, you can record the original int that was fed into the Gen function - rerunning the test with that seed is guaranteed to generate the same values, i.e. reproduce the bug.

Is it possible to create a discriminated union via a unit of measure tag in F#?

Is it possible to create a discriminated union type via a unit of measurement tag in F#?
I want to write sth. like the following:
type DomainObject =
| Pixel of int
| ScaledPixel of int
| Centimeter of float
| Unset
let var1 = 10<px> // should equal: let var1 = Pixel(10)
let var2 = 0<us> // should equal: let var2 = Unset
let process sth =
match sth with
| Pixel(p) -> ...
| Centimeter(c) -> ...
// etc.
With NumericLiterals such things are possible. But then one can only use a small amount of Literals like Neil P. showed.
As I said in the comment, the simple answer is no.
In a way, you are trying to misuse one F# feature (units of measure) to emulate a feature that might exist in other languages (suffix operators), which is probably a bad thing to do in the first place, because (even if it was possible), the resulting code would be quite confusing.
If you simply want to reverse the order of the arguments so that the number comes before the unit name, you can use the piping operator and write:
let var1 = 10 |> Pixel
let var2 = Unset
This essentially gives you a way to write "suffix operators", but using standard F# idioms.
I don't think that this special combination is possible but you can go with smart constructors if you like:
module Domain =
[<Measure>] type px
[<Measure>] type spx
[<Measure>] type cm
// ...
type DomainObject =
| Pixel of float<px>
| ScaledPixel of float<spx>
| Centimeter of float<cm>
| Unset
let inline pixel f = Pixel <| float f * 1.0<px>
let inline scaledPixel f = ScaledPixel <| float f * 1.0<spx>
let unset = Unset
// ...
let var1 = pixel 10
let var2 = unset
let process sth =
match sth with
| Pixel(p) -> ...
| Centimeter(c) -> ...
// etc.
I think this is reasonable close - if you want you can make the constructors private and add active-patterns (to reenable pattern-matching) or accessors to fully encapsulate the implementation-details.
If you get fancy you can even add (+), (-), ...
PS: the inline is to get the functions working with all kinds of numeric values ;)
PPS: I played a bit and the problem is indeed (as mentioned in the link you gave - that you can only have a very limited set of "suffixes" - namely Q, R, Z, I, N, and G) - for example this kindof works:
module NumericLiteralQ =
open Domain
let inline FromZero() = Pixel 0.0<px>
let inline FromOne() = Pixel 1.0<px>
let inline FromString (s:string) =
System.Double.Parse s * 1.0<px> |> Pixel
let inline FromInt32 (n:int) =
1.0<px> * float n |> Pixel
let inline FromInt64 (n:int64) =
1.0<px> * float n |> Pixel
but I think it's very uggly to write
let p = 5Q
instead of
let p = pixel 5
or
let p = 5 |> pixel

Int Option instead of Int in F#

I am having trouble with the following:
let safeDiv x y =
match (x,y) with
| (_, Some 0) -> None
| (Some xx, Some yy) -> Some (xx/yy)
| _ -> None
When I go to run this simple function in the interactive window of Visual Studio like so:
safeDiv 4 2
I get the following error...
This expression was expected to have type int option but here has type int.
Could it be I'm meant to use safeDiv Some(4) Some(2)? This doesn't work either...
Ok, this is overkill but I actually did something similar to this recently.
First I defined a computation expression builder for the option type:
type OptionBuilder() =
member this.Bind(x, f) = Option.bind f x
member this.Return(x) = Some x
member this.ReturnFrom(x) = x
let opt = new OptionBuilder()
And then I defined a function sub of type float -> float -> float option
let sub x y = if y = 0.0 then None else Some (x / y)
And finally I used the OptionBuilder to define saveDiv as float option -> float option -> float option
let safeDiv x y = opt { let! a = x
let! b = y
return! sub a b }
You can read more about computation expressions on wikibooks: http://en.wikibooks.org/wiki/F_Sharp_Programming/Computation_Expressions
And if you want to dive deeper into the theory behind this, you can read this paper by Tomas Petricek and Don Syme: http://www.cl.cam.ac.uk/~tp322/drafts/notations.pdf
Your second version was close.
It should be
safeDiv (Some(4)) (Some(2))
The extra brackets are required to make sure that functions are applied in the correct order.
You constructed a function that has the signature safeDiv : int option -> int option -> int option. You need to use an entry like safeDiv (Some 4) (Some 2) to use your function as is.
The problem is in the matching of (4, 2), of type int*int, with the expressions (_, Some 0) and (Some xx, Some yy). The whole function can be simplified:
let safeDiv x y =
match (x,y) with
| (_, 0) -> None
| (_, _) -> Some (x/y)
Making the following call valid
safeDiv 4 2

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