How to use Validation applicative from F# #1293
-
I've been using this library with a lot of C# code and now was writing some F# to interface with that codebase and I'm having trouble calling some existing code that uses module Validation =
open LanguageExt
let apply<'F, 'A, 'B, 'R>
(f: System.Func<'A, 'B, 'R>)
struct (a: Validation<'F, 'A>, b: Validation<'F, 'B>)
: Validation<'F, 'R> =
let t = System.ValueTuple.Create(a, b)
LanguageExt.Prelude.Apply<'F, 'A, 'B, 'R>(t, f) Any help? EDIT: oh I am on .Net 6 and F# 6 if that makes a difference. |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 3 replies
-
Ok, so the short answer to your question is that you need to treat the let apply<'F, 'A, 'B, 'R>
(f: System.Func<'A, 'B, 'R>)
struct (a: Validation<'F, 'A>, b: Validation<'F, 'B>)
: Validation<'F, 'R> =
let t = System.ValueTuple.Create(a, b)
t.Apply(f) The longer answer is to define an operator that does this in a much better way. First, I'll define the one and only wrapper needed for let apply (mf : Validation<'f, 'a -> 'b>) (ma : Validation<'f, 'a>) : Validation<'f, 'b> =
mf.Disjunction(ma)
.Map(fun _ -> (successValue mf) (successValue ma))
let map (f : 'a -> 'b) (ma : Validation<'f, 'a>) : Validation<'f, 'b> =
ma.Map(f) I'm using the same To get the value out of the let successValue (ma : Validation<'f, 'a>) : 'a =
ma.IfFail(fun () -> failwith "Validation monad is in a Fail state") This can be done with explicit casts in C#, but this will have the same effect. Next, let's create a couple of constructor functions for constructing a let success x : Validation<'f, 'a> =
Validation<'f, 'a>.Success(x)
let fail x : Validation<'f, 'a> =
Validation<'f, 'a>.Fail(Prelude.Seq1(x)) And finally, the apply and map operators. I have used the same let (<*>) = apply
let ($) = map You can now easily apply: let add = fun x y -> x + y
let mf = success add
let ma = success 123
let mb = success 456
let mr1 = mf <*> ma <*> mb
let mr2 = add $ ma <*> mb Note how I hope that helps. This is probably the one thing I wish I could do in C# (define operators that have different generics for each operand). Until then C# is stuck with tricks like the tuple extensions. |
Beta Was this translation helpful? Give feedback.
Ok, so the short answer to your question is that you need to treat the
Apply
function as an extension method and not a static method:The longer answer is to define an operator that does this in a much better way.
First, I'll define the one and only wrapper needed for
apply
(andmap
):