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.
Related
RE: What is the best way to pass generic function that resolves to multiple types
Please read the referenced link before going further below
I am trying to extend the concept and pass a generic function that takes 2 parameters and does something with them.
The static approach works, however the interface based one causes a compile error (see the code lines marked with //error):
The declared type parameter '?' cannot be used here since the type parameter cannot be resolved at compile time.
Does anyone know how to fix it?
module MyModule
type T = Content of int
with
static member (+) ((Content i1), (Content i2)) = Content (i1 + i2)
static member (*) ((Content i1), (Content i2)) = Content (i1 * i2)
type W = { Content: int }
with
static member (+) ({Content = i1}, {Content = i2}) = { Content = i1 + i2 }
static member (*) ({Content = i1}, {Content = i2}) = { Content = i1 * i2 }
type Sum = Sum with static member inline ($) (Sum, (x, y)) = x + y
type Mul = Mul with static member inline ($) (Mul, (x, y)) = x * y
let inline f1 (la: 'a list) (lb: 'b list) reducer =
let a = la |> List.reduce (fun x y -> reducer $ (x, y))
let b = lb |> List.reduce (fun x y -> reducer $ (x, y))
(a, b)
type I = abstract member Reduce<'a> : 'a -> 'a -> 'a
let f2 (la: 'a list) (lb: 'b list) (reducer: I) =
let a = la |> List.reduce reducer.Reduce
let b = lb |> List.reduce reducer.Reduce
(a, b)
let main ()=
let lt = [Content 2; Content 4]
let lw = [{ Content = 2 }; { Content = 4 }]
let _ = f1 lt lw Sum
let _ = f1 lt lw Mul
let _ = f2 lt lw { new I with member __.Reduce x y = x + y} //error
let _ = f2 lt lw { new I with member __.Reduce x y = x * y} //error
0
The problem with your attempt is that you can't use operators + or * on parameters x and y, because it's not known that their type 'a has those operators defined.
To answer your further question in comments about how to achieve it anyway - if you want to use multiplication and addition on any type 'a that the caller chooses, you have to specify that. For an interface method, the only way to do this is by constraining the type parameter 'a, and the only two kinds of constraints that .NET runtime supports are "has a parameterless constructor" and "implements a given interface or inherits from a given class".
The latter one would be useful in your case: make both types implement the interface and then constrain type parameter 'a to implement that interface:
type IArithmetic<'a> =
abstract member add : 'a -> 'a
abstract member mult : 'a -> 'a
type T = Content of int
with
interface IArithmetic<T> with
member this.add (Content y) = let (Content x) = this in Content (x + y)
member this.mult (Content y) = let (Content x) = this in Content (x * y)
type W = { Content: int }
with
interface IArithmetic<W> with
member this.add y = { Content = this.Content + y.Content }
member this.mult y = { Content = this.Content * y.Content }
type I = abstract member Reduce<'a when 'a :> IArithmetic<'a>> : 'a -> 'a -> 'a
// ^^^^^^^^^^^^^^^^^^^^^^^^^^
// the constraint right here
...
let _ = f2 lt lw { new I with member __.Reduce x y = x.add y }
let _ = f2 lt lw { new I with member __.Reduce x y = x.mult y }
Is this a bit awkward? I guess so, but you're kind of doing the same thing for the SRTP version, so why not?
The core idea is: if you want your Reduce method to work not with just any type, but only with types that can do certain things, you have to specify what those things are. In the SRTP case you're doing that by defining the (+) and (*) operators. In the interface case you're doing that by implementing the interface.
Q: But can I make the interface somehow pick up the (+) and (*) operators?
A: In general, no. The .NET runtime just doesn't support the kind of constraints like "any type that has a method with certain signature". This means that such constraints can't be compiled down to IL, which means they can't be used in an interface implementation.
And this is the price you pay for using SRTPs: all those inline functions - they don't get compiled to IL, they always get expanded (inserted, substituted) at use sites. For small, simple functions, this is no big deal. But if your whole program is like that, you might see some unexpected compiled code bloat, potentially translating to slower startup time etc.
Having said all that, I must note that the code you're showing is toy POC kind of code, not intended to solve any real, practical problem. And as such, most musings on it are in danger of being completely useless.
If you have an actual problem in mind, perhaps try sharing it, and somebody would suggest the best solution for that specific case.
In particular, I have a nagging feeling that you might not actually need higher-rank functions (that's what it's called when a function doesn't lose genericity when passed as parameter).
type Interpreter<'a> =
| RegularInterpreter of (int -> 'a)
| StringInterpreter of (string -> 'a)
let add<'a> (x: 'a) (y: 'a) (in_: Interpreter<'a>): 'a =
match in_ with
| RegularInterpreter r ->
x+y |> r
| StringInterpreter r ->
sprintf "(%s + %s)" x y |> r
The error message of it not being able to resolve 'a at compile time is pretty clear to me. I am guessing that the answer to the question of whether it is possible to make the above work is no, short of adding functions directly into the datatype. But then I might as well use an interface, or get rid of generic parameters entirely.
Edit: Mark's reply does in fact do what I asked, but let me extend the question as I did not explain it adequately. What I am trying to do is do with the technique above is imitate what what was done in this post. The motivation for this is to avoid inlined functions as they have poor composability - they can't be passed as lambdas without having their generic arguments specialized.
I was hoping that I might be able to work around it by passing an union type with a generic argument into a closure, but...
type Interpreter<'a> =
| RegularInterpreter of (int -> 'a)
| StringInterpreter of (string -> 'a)
let val_ x in_ =
match in_ with
| RegularInterpreter r -> r x
| StringInterpreter r -> r (string x)
let inline add x y in_ =
match in_ with
| RegularInterpreter r ->
x in_ + y in_ |> r
| StringInterpreter r ->
sprintf "(%A + %A)" (x in_) (y in_) |> r
let inline mult x y in_ =
match in_ with
| RegularInterpreter r ->
x in_ * y in_ |> r
| StringInterpreter r ->
sprintf "(%A * %A)" (x in_) (y in_) |> r
let inline r2 in_ = add (val_ 1) (val_ 3) in_
r2 (RegularInterpreter id)
r2 (StringInterpreter id) // Type error.
This last line gives a type error. Is there a way around this? Though I'd prefer the functions to not be inlined due to the limits they place on composability.
Remove the type annotations:
let inline add x y in_ =
match in_ with
| RegularInterpreter r ->
x + y |> r
| StringInterpreter r ->
sprintf "(%A + %A)" x y |> r
You'll also need to make a few other changes, which I've also incorporated above:
Change the format specifiers used with sprintf to something more generic. When you use %s, you're saying that the argument for that placeholder must be a string, so the compiler would infer x and y to be string values.
Add the inline keyword.
With these changes, the inferred type of add is now:
x: ^a -> y: ^b -> in_:Interpreter<'c> -> 'c
when ( ^a or ^b) : (static member ( + ) : ^a * ^b -> int)
You'll notice that it works for any type where + is defined as turning the input arguments into int. In practice, that's probably going to mean only int itself, unless you define a custom operator.
FSI smoke tests:
> add 3 2 (RegularInterpreter id);;
val it : int = 5
> add 2 3 (StringInterpreter (fun _ -> 42));;
val it : int = 42
The compiler ends up defaulting to int, and the kind of polymorphism you want is difficult to achieve in F#. This article articulates the point.
Perhaps, you could work the dark arts using FSharp.Interop.Dynamic but you lose compile time checking which sort of defeats the point.
I've come to the conclusion that what I am trying to is impossible. I had a hunch that it was already, but the proof is in the following:
let vale (x,_,_) = x
let adde (_,x,_) = x
let multe (_,_,x) = x
let val_ x d =
let f = vale d
f x
let add x y d =
let f = adde d
f (x d) (y d)
let mult x y d =
let f = multe d
f (x d) (y d)
let in_1 =
let val_ (x: int) = x
let add x y = x+y
let mult x y = x*y
val_,add,mult
let in_2 =
let val_ (x: int) = string x
let add x y = sprintf "(%s + %s)" x y
let mult x y = sprintf "(%s * %s)" x y
val_,add,mult
let r2 d = add (val_ 1) (val_ 3) d
//let test x = x in_1, x in_2 // Type error.
let a2 = r2 in_1 // Works
let b2 = r2 in_2 // Works
The reasoning goes that if it cannot be done with plain functions passed as arguments, then it definitely won't be possible with interfaces, records, discriminated unions or any other scheme. The standard functions are more generic than any of the above, and if they cannot do it then this is a fundamental limitation of the language.
It is not the lack of HKTs that make the code ungeneric, but something as simple as this. In fact, going by the Finally Tagless paper linked to in the Reddit post, Haskell has the same problem with needing to duplicate interpreters without the impredicative types extension - though I've looked around and it seem that impredicative types will be removed in the future as the extension is difficult to maintain.
Nevertheless, I do hope this is only a current limitation of F#. If the language was dynamic, the code segment above would in fact run correctly.
Unfortunately, it's not completely clear to me what you're trying to do. However, it seems likely that it's possible by creating an interface with a generic method. For example, here's how you could get the code from your answer to work:
type I = abstract Apply : ((int -> 'a) * ('a -> 'a -> 'a) * ('a -> 'a -> 'a)) -> 'a
//let test x = x in_1, x in_2 // Type error.
let test (i:I) = i.Apply in_1, i.Apply in_2
let r2' = { new I with member __.Apply d = add (val_ 1) (val_ 3) d }
test r2' // no problem
If you want to use a value (e.g. a function input) generically, then in most cases the cleanest way is to create an interface with a generic method whose signature expresses the required polymorphism.
I want to simplify expression if(x == 1 || x == 2).
I wish I could write if(x == 1 or 2) but there is no syntax for that.
Other possibility is to use Contains or Any method like: if([1,2].Contains(x)) but this involves unnecessary call.
Can I create some operator which allows me to do this ?
In Nemerle language I can write macro:
macro #|||(left, right)
match (left)
| <[ $x == $y ]> => <[ $x == $y || $x == $right ]>
| _ => Message.Error("Error"); <[ ]>
And then usage:
if (x == 1 ||| 2) { .. }
Can I create operator in such way in F# ?
I agree with Brian's comment that constructing a macro in order to save three characters is probably not a good idea. This will only make the program harder to read (for those who do not know your custom macros or changed meaning of operators).
Moreover, it is quite likely that you could write the same logic in a more concise way using standard F# constructs like pattern matching. For example:
match x with
| 1 | 2 -> printfn "yes"
| _ -> printfn "no"
The idiomatic solution will depend on the concrete case, which is hard to judge from the example you gave.
You could use |> to accomplish this, borrowing from a common use of one of the haskell monoid instances.
let appendResults f g = (fun x -> f(x) || g(x))
let f x = x=1
let g x = x=2
let inline (>>||) x y = (appendResults f g) x y
let x = 1
if(x |> (1 >>|| 2)) then printfn "true" else printfn "false"
For arbitrary numbers of arguments, just mimic the relevant mconcat method from haskell for the same effect, perhaps like this:
let rec concatResults = function
| [] -> (fun x -> false)
| (x:xs) -> appendResults x (concatResults xs)
Honestly though, you may as well just use Contains. If there is any special overhead doing that I doubt it really matters.
I agree with Brian and Tomas; it makes a little practical sense to invent your own macros that might be used just a few times.
However, I do find it very interesting from the point of studying the internals of functional languages.
Consider this:
// Generic
let inline mOp1<'a> op sample x = op sample x, sample
let inline mOp2<'a> op1 op2 (b, sample) x = op1 b (op2 sample x), sample
// Implementation for (=) and (||)
let (==) = mOp1 (=)
let (|=) = mOp2 (||) (=)
// Use
let ret1 = x == 1 |= 2 |> fst
You may find more details, other operators, and performance measurement here: https://stackoverflow.com/a/11552429/974789
This is slightly hackish, but it does work
let x = 1
let inline (|||) a b = [a;b]
let inline (==) a b = b |> List.exists (fun t -> t=a)
if x == (1 ||| 2) then printfn "true" else printfn "false"
It requires a custom operator for both or and equals. It would not be hard to modify this to support arbitrary or chains
Of course if you only need 2 numbers you can do
let x = 1
let inline (|||) a b = (a,b)
let inline (==) a (c,d) = a=c ||a=d
if x == (1 ||| 2) then printfn "true" else printfn "false"
This works by converting a tupple to an array, so do not expect the best performance.
let inline (==) a b =
Microsoft.FSharp.Reflection.FSharpValue.GetTupleFields(b)
|> Array.exists((=) a)
Example:
3 == (1,2) // false
3 == (1,2,3) // true
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.
F# allows to use checked arithmetics by opening Checked module, which redefines standard operators to be checked operators, for example:
open Checked
let x = 1 + System.Int32.MaxValue // overflow
will result arithmetic overflow exception.
But what if I want to use checked arithmetics in some small scope, like C# allows with keyword checked:
int x = 1 + int.MaxValue; // ok
int y = checked { 1 + int.MaxValue }; // overflow
How can I control the scope of operators redefinition by opening Checked module or make it smaller as possible?
You can always define a separate operator, or use shadowing, or use parens to create an inner scope for temporary shadowing:
let f() =
// define a separate operator
let (+.) x y = Checked.(+) x y
try
let x = 1 +. System.Int32.MaxValue
printfn "ran ok"
with e ->
printfn "exception"
try
let x = 1 + System.Int32.MaxValue
printfn "ran ok"
with e ->
printfn "exception"
// shadow (+)
let (+) x y = Checked.(+) x y
try
let x = 1 + System.Int32.MaxValue
printfn "ran ok"
with e ->
printfn "exception"
// shadow it back again
let (+) x y = Operators.(+) x y
try
let x = 1 + System.Int32.MaxValue
printfn "ran ok"
with e ->
printfn "exception"
// use parens to create a scope
(
// shadow inside
let (+) x y = Checked.(+) x y
try
let x = 1 + System.Int32.MaxValue
printfn "ran ok"
with e ->
printfn "exception"
)
// shadowing scope expires
try
let x = 1 + System.Int32.MaxValue
printfn "ran ok"
with e ->
printfn "exception"
f()
// output:
// exception
// ran ok
// exception
// ran ok
// exception
// ran ok
Finally, see also the --checked+ compiler option:
http://msdn.microsoft.com/en-us/library/dd233171(VS.100).aspx
Here is a complicated (but maybe interesting) alternative. If you're writing something serious then you should probably use one of the Brians suggestions, but just out of curiosity, I was wondering if it was possible to write F# computation expression to do this. You can declare a type that represents int which should be used only with checked operations:
type CheckedInt = Ch of int with
static member (+) (Ch a, Ch b) = Checked.(+) a b
static member (*) (Ch a, Ch b) = Checked.(*) a b
static member (+) (Ch a, b) = Checked.(+) a b
static member (*) (Ch a, b) = Checked.(*) a b
Then you can define a computation expression builder (this isn't really a monad at all, because the types of operations are completely non-standard):
type CheckedBuilder() =
member x.Bind(v, f) = f (Ch v)
member x.Return(Ch v) = v
let checked = new CheckedBuilder()
When you call 'bind' it will automatically wrap the given integer value into an integer that should be used with checked operations, so the rest of the code will use checked + and * operators declared as members. You end up with something like this:
checked { let! a = 10000
let! b = a * 10000
let! c = b * 21
let! d = c + 47483648 // !
return d }
This throws an exception because it overflows on the marked line. If you change the number, it will return an int value (because the Return member unwraps the numeric value from the Checked type). This is a bit crazy technique :-) but I thought it may be interesting!
(Note checked is a keyword reserved for future use, so you may prefer choosing another name)