How can I defined the width of a random number?
let randomNumber = System.Random()
let randomBarcodePart2 = randomNumber.Next(**000000, 999999**)
I have this now, but is it possible to generate a random number, where we only defined the width.
Like this:
let randomBarcodePart2 = randomNumber.Next(6)
simple example with printf:
let t = randomNumber.Next(0,999999)
printfn "%07i" t
You can do this with a type extension:
type System.Random with
member x.Width w =
x.Next(0, pown 10 w - 1)
|> sprintf "%0*d" w
Here's a few outputs
Random().Width 6;;
val it : string = "985326"
Random().Width 9;;
val it : string = "803426947"
Random().Width 1;;
val it : string = "6"
Related
Consider a generic container like:
type Foo<'t> =
{
Foo : 't
}
This generic function works OK:
module Foo =
let inline emptyFoo () =
{
Foo = LanguagePrimitives.GenericZero
}
But this value does not:
module Foo =
let emptyFoo =
{
Foo = LanguagePrimitives.GenericZero
}
This is because the compiler infers emptyFoo to have type Foo<obj>.
However, the standard library has generic values like List.empty, so how is that achieved there?
You have to make it explicitly generic.
List.empty is implemented like this:
let empty<'T> = ([ ] : 'T list)
You could implement a List by yourself, with an empty. It looks like this.
type L<'a> =
| Null
| Cons of 'a * L<'a>
module L =
let empty = Null
let xs = Cons(1, Cons(2, L.empty))
let ys = Cons(1.0,Cons(2.0,L.empty))
So, why does L.empty in this case works in a generic way? Because the value Null has no special value attached to it. You could say, it is compatible with every other generic.
In your Record on the other hand, you always must produce a value. LanguagePrimitive.GenericZero is not some Generic value. It help so to resolve to a special zero value, and this value is determined by the other code you write.
For example
let x = LanguagePrimitives.GenericZero
is also obj
let x = LanguagePrimitives.GenericZero + 1
will be int. And
let x = LanguagePrimitives.GenericZero + 1.0
will be float. So in some case you can think of GenericZero just as a placeholder for zero for the special type you need, but the code needs to determine at this point, which type you want.
You could change your type, with an option to provide a real empty.
type Foo<'t> = {
Foo: 't option
}
module Foo =
let empty = { Foo = None }
let x = Foo.empty // Foo<'a>
let y = { x with Foo = Some 1 } // Foo<int>
let z = { x with Foo = Some 1.0 } // Foo<float>
Zero Member
Maybe you want a Zero Member on some types. For example
type Vector3 = {X:float; Y:float; Z:float} with
static member create x y z = {X=x; Y=y; Z=z}
static member (+) (a,b) = Vector3.create (a.X + b.X) (a.Y + b.Y) (a.Z + b.Z)
static member Zero = Vector3.create 0.0 0.0 0.0
static member DivideByInt(a,b) =
Vector3.create
(LanguagePrimitives.DivideByInt a.X b)
(LanguagePrimitives.DivideByInt a.Y b)
(LanguagePrimitives.DivideByInt a.Z b)
then you can write
let xs = [1;2;3]
let ys = [Vector3.create 1.0 1.0 1.0; Vector3.create 1.0 1.0 1.0]
let inline sum xs =
List.fold (fun a b -> a + b) LanguagePrimitives.GenericZero xs
let sumx = sum xs // int: 6
let sumy = sum ys // Vector3: 2.0 2.0 2.0
/!\ F# brand newbie /!\
I have this code
#r #"..\packages\Accord.3.4.0\lib\net40\Accord.dll"
#r #"..\packages\Accord.Statistics.3.4.0\lib\net40\Accord.Statistics.dll"
#r #"..\packages\Accord.Math.3.4.0\lib\net40\Accord.Math.dll"
open Accord
open Accord.Statistics.Models.Regression.Linear
let input = [|1,1.;2,2.;3,2.25;4,4.75;5,5.|]
let x = input |> Array.map(fun (x,y) -> float x)
let y = input |> Array.map(fun (x,y) -> y)
let regression = SimpleLinearRegression()
let sse = regression.Regress(x,y)
let intercept = regression.Intercept
let slope = regression.Slope
let mse = sse/float x.Length
let rmse = sqrt mse
let r2 = regression.CoefficientOfDetermination(x,y)
Which gives me the result
val input : (int * float) [] = [|(1, 1.0); (2, 2.0); (3, 2.25); (4, 4.75); (5, 5.0)|]
val x : float [] = [|1.0; 2.0; 3.0; 4.0; 5.0|]
val y : float [] = [|1.0; 2.0; 2.25; 4.75; 5.0|]
val regression : SimpleLinearRegression = y(x) = 1,075x + -0,224999999999998
val sse : float = 1.06875
val intercept : float = -0.225
val slope : float = 1.075
val mse : float = 0.21375
val rmse : float = 0.4623310502
val r2 : float = 0.9153465347
How is that possible that SimpleLinearRegression function works but we don't even pass it x and y?
Can you point me to a reference to understand what is this F# magic behind that?
I am guessing you are using the F-Sharp Interactive, and sending all of the code to FSI in one swoop.
The magic is that the code is executed first, then the results are written. Even if the sequence of 'val' outputs get a bit counter intuitive that way.
I can illustrate with this example (for future readers):
let mutable a = 1
let f = a <- 2; fun () -> 3
do a <- f ()
which gives this output in FSI:
val mutable a : int = 3
val f : (unit -> int)
val it : unit = ()
notice how a is updated to its final value before being printed (we never even see 1 and 2, even though that are the values of a after line one and two respectively).
This code:
let mutable x : Nullable<int64> = new Nullable<int64> 99L
let y : int64 = 88L
x <- y
produces this compile time error:
This expression was expected to have type Nullable but here has type int64
I understand the error, what I would like to know is what is the correct way (cast?) to assign the value in y (88) to x?
Use the System.Nullable constructor; for example:
>
let mutable x = System.Nullable (99L)
let y = 88L
x <- System.Nullable y;;
val mutable x : Nullable<int64> = 88L
val y : int64 = 88L
val it : unit = ()
I know that variables in F# are immutable by default.
But, for example in F# interactive:
> let x = 4;;
val x : int = 4
> let x = 5;;
val x : int = 5
> x;;
val it : int = 5
>
So, I assign 4 to x, then 5 to x and it's changing. Is it correct? Should it give some error or warning? Or I just don't understand how it works?
When you write let x = 3, you are binding the identifier x to the value 3. If you do that a second time in the same scope, you are declaring a new identifier that hides the previous one since it has the same name.
Mutating a value in F# is done via the destructive update operator, <-. This will fail for immutable values, i.e.:
> let x = 3;;
val x : int = 3
> x <- 5;;
x <- 5;;
^^^^^^
stdin(2,1): error FS0027: This value is not mutable
To declare a mutable variable, add mutable after let:
let mutable x = 5;;
val mutable x : int = 5
> x <- 6;;
val it : unit = ()
> x;;
val it : int = 6
But what's the difference between the two, you might ask? An example may be enough:
let i = 0;
while i < 10 do
let i = i + 1
()
Despite the appearances, this is an infinite loop. The i declared inside the loop is a different i that hides the outer one. The outer one is immutable, so it always keeps its value 0 and the loop never ends. The correct way to write this is with a mutable variable:
let mutable i = 0;
while i < 10 do
i <- i + 1
()
x is not changed, it's just hidden by next declaration.
For example:
> let x = 4;;
val x : int = 4
> let x = "abc";;
val x : string = "abc"
>
You're not assigning 5 to x, you are defining a new variable.
The following example shows that there are two distinct variables.
(It also shows that you can "access" the old x if it is in a closure, used by another function):
let x = 5;;
let f y = y+x;;
f 10;;
let x = 0;;
f 10;;
yields
>
val x : int = 5
>
val f : int -> int
> val it : int = 15
>
val x : int = 0
> val it : int = 15
as you see, both calls to f use the first variable x. The definition let x = 0;; defines a new variable x, but does not redefines f.
Here's a minimal example illustrating identifier "shadowing" (i.e. hiding) in F#:
let x = 0
do //introduce a new lexical scope
let x = 1 //"shadow" (i.e. hide) the previous definition of x
printfn "%i" x //prints 1
//return to outer lexical scope
printfn "%i" x //prints 0, proving that our outer definition of x was not mutated by our inner definition of x
Your example is actually a bit more complex, because you are working in the F# Interactive (FSI). FSI dynamically emits code that looks something like the following in your example:
module FSI_0001 =
let x = 4;;
open FSI_0001 //x = 4 is now available in the top level scope
module FSI_0002 =
let x = 5;;
open FSI_0002 //x = 5 is now available in the top level scope, hiding x = 4
module FSI_0003 =
let it = x;;
open FSI_0003
//... subsequent interactions
in F#, How to make a function wrapper (x:'T) to wrap any inputs to an array of array, say: wrapper(1) = [|[|1|]|]; wrapper([|1|]) = [|[|1|]|]; and wrapper([|[|1|]|]) = [|[|1|]|]; something like below does not work:
let wrapper (x:'T) =
let y =
if not <| x.GetType().IsArray then [|[|x|]|]
elif not <| x.[0].GetType().IsArray then [|x|]
else x
y
The following seems to work:
let wrapper<'a, 'b> (x:'a) =
match box x with
| null -> null
| :? array<array<'b>> as y -> y
| :? array<'b> as y -> [|y|]
| y -> [|[|unbox y|]|]
The signature is 'a -> array<array<'b>>.
In response to your comment: this sort of thing can be done in statically-typed languages--and, arguably better than in a dynamic language--but/because stepping outside the type system must be explicit (e.g., box/unbox).
Here's a reflection based solution which will accept inputs of arbitrary nested array depth:
open System.Text.RegularExpressions
let wrapper input =
let ty = input.GetType()
if ty.IsArray |> not then
[|[|input |> unbox|]|]
else
let depth = Regex.Matches(ty.Name, "\[\]", RegexOptions.Compiled).Count
let rec findInnerItem curDepth curArray =
let innerItem = curArray.GetType().GetMethod("Get").Invoke(curArray, [|box 0|])
if curDepth = depth then
innerItem
else
findInnerItem (curDepth+1) innerItem
let innerItem = findInnerItem 1 input
[|[|innerItem |> unbox|]|]
Usage in FSI:
val wrapper : 'a -> 'b [] []
> let x : int[][] = wrapper 1;;
val x : int [] [] = [|[|1|]|]
> let x : int[][] = wrapper [|1|];;
val x : int [] [] = [|[|1|]|]
> let x : int[][] = wrapper [|[|1|]|];;
val x : int [] [] = [|[|1|]|]
> let x : int[][] = wrapper [|[|[|1|]|]|];;
val x : int [] [] = [|[|1|]|]
> let x : int[][] = wrapper [|[|[|[|1|]|]|]|];;
val x : int [] [] = [|[|1|]|]
> let x : int[][] = wrapper [|[|[|[|[|1|]|]|]|]|];;
val x : int [] [] = [|[|1|]|]
> let x : int[][] = wrapper [|[|[|[|[|[|1|]|]|]|]|]|];;
val x : int [] [] = [|[|1|]|]
You can't, that's not a well-typed function (try to write out the type signature).
You function needs to "wrap any inputs to an array of array". As par this statement the solution is as simple as:
let wrapper (x:'T) = [|[|x|]|];
But then the examples you have given are not as par your function definition.
i.e wrapper([|1|]) = [|[|1|]|] should be wrapper([|1|]) = [|[|[|1|]|]|] as par your function definition.