how to replicate this C# initialization code in F# - f#

I have this in C#:
_RestClient.ConfigureWebRequest(r =>
{
r.ServicePoint.Expect100Continue = false;
r.KeepAlive = true;
});
what is the syntax to replicate this in F#?

Lambda-expressions in F# are denoted fun x -> ... - equivalent to C# x => ...
Mutation (aka "assignment") is denoted x <- y - equivalent to C# x = y
So, to put that all together, you'd get this:
_RestClient.ConfigureWebRequest(fun r ->
r.ServicePoint.Expect100Continue <- false
r.KeepAlive <- true
)

Related

Implementing let! ... and! ... in a custom Computation Expression

I want to add support to my Computation Expression builder for this construct:
let f =
foo {
let! x =
foo {
return 1
}
and! y =
foo {
return 2
}
return x + y
}
The compiler says I must implement either Bind2 or MergeSource. However, I cannot find them in the docs.
What signatures should these have? Can you give a simple example?
Here's a simple builder that works with your example:
type Foo<'t> = MkFoo of 't
type FooBuilder() =
member _.Bind(MkFoo x, f) = f x
member _.Return(x) = MkFoo x
member _.MergeSources(MkFoo x, MkFoo y) = MkFoo (x, y)
let foo = FooBuilder()
let f =
foo {
let! x = foo { return 1 }
and! y = foo { return 2 }
return x + y
}
printfn "%A" f // output: MkFoo 3
The purpose of MergeSources is to create a tuple of results that will be automatically de-tupled by the compiler. You might also find this example and this SO question useful.

Explanation of Monad laws in F#

Here is Explanation of Monad laws in Haskell.
How do explain Monad laws in F#?
bind (M, return) is equivalent to M.
bind ((return x), f) is equivalent to f x.
bind (bind (m, f),g) is equivalent to bind(m, (fun x -> bind (f x, g))).
I think that a good way to understand them in F# is to look at what they mean using the computation expression syntax. I'll write m for some computation builder, but you can imagine that this is async or any other computation type.
Left identity
m { let! x' = m { return x } = m { let x' = x
return! f x' } return! f x' }
Right identity
m { let! x = comp = m { return! comp }
return x }
Associativity
m { let! x = comp = m { let! y = m { let! x = comp
let! y = f x return! f x }
return! g y } return! g y }
The laws essentially tell you that you should be able to refactor one version of the program to the other without changing the meaning - just like you can refactor ordinary F# programs.

In FsCheck, how to generate a test record with non-negative fields?

In F#, I have a record with a few fields:
type myRecord = { a:float; b:float; c:float }
I am using FsCheck to test some properties which use this record.
For (a contrived) example,
let verify_this_property (r:myRecord) = myFunction(r) = (r.a * r.b) / r.c
Due to the internal implementation restrictions of myFunction, I would like to have FsCheck create test cases in which each of the fields a,b,c are restricted to non-negative floats.
I suspect this requires creating a generator for myRecord, but I have not been able to find any examples of how to do this.
Can anyone supply guidance?
Try this:
type Generators =
static member arbMyRecord =
fun (a,b,c) -> { myRecord.a = a; b = b; c = c }
<!> (Arb.generate<float> |> Gen.suchThat ((<) 0.) |> Gen.three)
|> Arb.fromGen
Arb.register<Generators>() |> ignore
Check.Quick verify_this_property
The <!> is an infix map, useful for applicative style. This is an equivalent generator:
type Generators =
static member arbMyRecord =
Arb.generate<float>
|> Gen.suchThat ((<) 0.)
|> Gen.three
|> Gen.map (fun (a,b,c) -> { myRecord.a = a; b = b; c = c })
|> Arb.fromGen
If you don't want to globally register your generator, you can use forAll:
Check.Quick (forAll Generators.arbMyRecord verify_this_property)
Shrinking left as an exercise ;)
You can avoid creating custom generator by using FsCheck conditional properties
let verify_this_property (r:myRecord) =
(r.a > 0.0 && r.b > 0.0 && r.c > 0.0) ==> lazy (myFunction r = (r.a * r.b) * r.c)
Though this will result in (substantially?) slower execution of the test since FsCheck will have to discard all unsuitable test entries.

Is there a standard option workflow in F#?

Is there an option (maybe) wokflow (monad) in the standrd F# library?
I've found a dozen of hand-made implementations (1, 2) of this workflow, but I don't really want to introduce non-standard and not very trusted code into my project. And all imaginable queries to google and msdn gave me no clue where to find it.
There's no standard computation builder for options, but if you don't need things like laziness (as added in the examples you linked) the code is straightforward enough that there's no reason not to trust it (particularly given the suggestively named Option.bind function from the standard library). Here's a fairly minimal example:
type OptionBuilder() =
member x.Bind(v,f) = Option.bind f v
member x.Return v = Some v
member x.ReturnFrom o = o
member x.Zero () = None
let opt = OptionBuilder()
There's no Maybe monad in the standard F# library. You may want to look at FSharpx, a F# extension written by highly-qualified members of F# community, which has quite a number of useful monads.
I've create an opensource library FSharp.Interop.NullOptAble available on nuget.
It not only works as an option workflow, but it works as a null or nullable workflow as well.
let x = Nullable(3)
let y = Nullable(3)
option {
let! x' = x
let! y' = y
return (x' + y')
} (* |> should equal (Some 6) *)
Works just as well as
let x = Some(3)
let y = Some(3)
option {
let! x' = x
let! y' = y
return (x' + y')
} (* |> should equal (Some 6) *)
Or even
let x = "Hello "
let y = "World"
option {
let! x' = x
let! y' = y
return (x' + y')
} (* |> should equal (Some "Hello World") *)
And if something is null or None
let x = "Hello "
let y:string = null
option {
let! x' = x
let! y' = y
return (x' + y')
} (* |> should equal None *)
Finally if you have a lot of nullable type things, I have a cexpr for chooseSeq {} and if you yield! something null/None it just doesn't get yielded.
See more examples here.

Strange error and other strange behavior with generic unit of measure structs in F#

I have this type:
type Vector3<[<Measure>]'u> =
struct
val x:float32<'u>
val y:float32<'u>
val z:float32<'u>
end
new(x, y, z) = { x = x; y = y; z = z }
When I try to make a default instance, it gives me a strange error that I couldn't find any information on Google about:
Error 5 The default, zero-initializing constructor of a struct type may only be used if all the fields of the struct type admit default initialization
So okay, I can just use the default constructor to set everything to 0 with. Or not.
let f = Vector3(0.f<N>, 0.f<N>, 0.f<N>)
Gives me an error:
Error 1 This expression was expected to have type float32 but here has type float32
This only seems to happen when I use this instance in a subsequent calculation; otherwise, it correctly resolves the type of f as being Vector3<N>. Giving the constructor the type, as in Vector3<N>(...) seems to also solve the problem, which is really strange.
Is there something I'm doing wrong?
There must be something wrong elsewhere in your code. If you reset F# Interactive, open a new empty F# Script file and paste the following code (and then run it in FSI), then everything works just fine for me:
type Vector3<[<Measure>]'u> =
struct
val x:float32<'u>
val y:float32<'u>
val z:float32<'u>
end
new(x, y, z) = { x = x; y = y; z = z }
[<Measure>] type N
let f = Vector3(0.f<N>, 0.f<N>, 0.f<N>)
I would recommend writing the code using implicit constructor syntax which is more succinct and more idiomatic F# (the struct .. end declaration is still allowed, but it has been used mainly in old versions of F#). Default constructor doesn't seem to work in this scenario, but you can use static member:
[<Struct>]
type Vector3<[<Measure>]'u>(x:float32<'u>, y:float32<'u>, z:float32<'u>) =
member this.X = x
member this.Y = y
member this.Z = z
static member Empty : Vector3<'u> = Vector3(0.f<_>, 0.f<_>, 0.f<_>)
[<Measure>] type N
let f1 = Vector3<N>.Empty
let f2 = Vector3(0.f<N>, 0.f<N>, 0.f<N>)
f1.X + f2.X
You need to specify the Default Value attribute for val fields:
type Vector3<[<Measure>]'u> =
struct
[<DefaultValue(false)>] val mutable x:float32<'u>
[<DefaultValue(false)>] val mutable y:float32<'u>
[<DefaultValue(false)>] val mutable z:float32<'u>
end
member X.Init(x,y,z) =
X.x <- x
X.y <- y
X.z <- z
Or use record types:
type Vector3<[<Measure>]'u> = { x : float32<'u>; y : float32<'u> ; z : float32<'u> }
[<Measure>] type N
let v = { x = 10.0F<N>; y = 10.0F<N>; z = 10.0F<N> }
UPDATE:
type Vector3<[<Measure>]'u> =
struct
val x:float32<'u>
val y:float32<'u>
val z:float32<'u>
new(X, Y, Z) = { x = X; y = Y; z = Z }
end

Resources