Threading params in f# - f#

I have the following issue - a handful of functions and 2 types where each of the functions takes at least 2 params (one of each defined type).
Now those types are parametrized and can only be used with those functions if their generic type params fit.
type Record<'a, 'b> = { first: 'a; second: 'b }
type Lens<'a, 'b> = Lens of 'a * 'b
let someFn lens rec : Record<'a, 'b> = ....
let anotherFn lens rec : Record<'a, 'b> = ...
let aThirdFn lens rec : Record<'a, 'b> = ...
//and potentially a dozen functions more that might or might not return a record
The usage scenario is something like this
let workflow1 () =
let intIntLens = Lens (1, 1)
let intIntRec = { first = 10; second = 100}
intIntRec
|> someFn intIntLens
|> anotherFn intIntLens
|> aThirdFn intIntLens
let workflow2 () =
let strIntLens = Lens ("foo", 1)
let strIntRec = { first = "bar"; second = 100}
strIntRec
|> someFn strIntLens
|> someFn strIntLens
|> aThirdFn strIntLens
|> anotherFn strIntLens
|> someFn strIntLens
Now for any given workflow the lens type stays the same but record is being somehow processed.
However I have to thread the lens into each of those functions which is somehow boring.
One obvious option would be to have a mutable module level variable. Which I assume wouldnt work for much long in the face of concurrent code.
So what is the best approach to get rid of the lens param here?

If your functions always take and return the same type (meaning they themselves are all of the same type), you could just make a list of them and apply in order:
let ap lens fns rec = Seq.fold (fun r f -> f lens r) rec fns
let workflow2 () =
let strIntLens = Lens ("foo", 1)
let strIntRec = { first = "bar"; second = 100}
ap strIntLens [someFn; someFn; aThirdFn; anotherFn; someFn] strIntRec
I can't see how the functions could be of different types, but perhaps this is just a toy example, and your real problem actually does deal with functions of different types.
If that is the case, here's a slightly less elegant solution: define a pipe locally to close the lens within it.
let workflow2 () =
let strIntLens = Lens ("foo", 1)
let strIntRec = { first = "bar"; second = 100}
let (|*>) r f = f strIntLens r
strIntLens
|*> someFn
|*> someFn
|*> aThirdFn
|*> anotherFn
|*> someFn
(Note that I did not reuse the standard pipe name |>. Though technically possible, that would make the code less readable)
Finally, you could go all-out on the problem, and combine input with lens in a single data structure, then create a custom pipe to work with such structure, which will apply the function, but tunnel the lens:
type RecAndLens<'a, 'b> = { rec: Record<'a, 'b>; lens: Lens<'a, 'b> }
let (|*>) rl f = { rec = f rl.lens rl.rec; lens = rl.lens }
let workflow2 () =
...
{ rec = strIntRec; lens = strIntLens }
|*> someFn
|*> someFn
|*> aThirdFn
|*> anotherFn
|*> someFn
This final approach would be a "long-term" kind of foundation, in case you're building a highly reusable library or something.
Technically, for a quick-and-dirty proof of concept, you could just use a tuple instead of the RecAndLens record:
let (|*>) (rec,lens) f = f lens rec, lens
let workflow2 () =
...
(strIntRec, strIntLens)
|*> someFn
|*> someFn
|*> aThirdFn
|*> anotherFn
|*> someFn
But this would be less sound, more error-prone (smells a bit of primitive obsession).

Related

FsCheck, I am not getting `Prop.forAll` to work (F#)

I am not coming right with FsCheck, when I try and use Prop.forAll.
I have created two tests to demonstrate what I am doing, expecting them both to fail.
type Data = { value: int }
type NeverAOne =
static member Data () =
Arb.generate<int>
|> Gen.filter (fun x -> x <> 1)
|> Gen.map (fun x -> { value = x })
|> Arb.fromGen
[<Property(Arbitrary = [| typeof<NeverAOne> |] )>] (* Fails *)
let ``Test One`` (x: Data) =
x.value = 1
[<Fact>]
let ``Test Two`` () = (* Passes *)
Prop.forAll (NeverAOne.Data ()) (fun x -> x.value = 1)
In this sample, Test Two passes. If I add breakpoints, I can see it is because no data is generated, so it iterates through 0 samples, which means none fail.
I am convinced that I am using Prop.forAll wrong, but though everything I have read through, I cannot find it.
If you mark the test as a plain Xunit Fact (rather than as a FsCheck Property), you have to explicitly check the property:
[<Fact>]
let ``Test Two`` () =
let prop = Prop.forAll (NeverAOne.Data ()) (fun x -> x.value = 1)
Check.QuickThrowOnFailure prop
The result I get is then:
System.Exception : Falsifiable, after 1 test (0 shrinks) (StdGen (74764374, 296947750)):
Original:
{ value = -2 }
Or you can just mark the test as a Property, of course:
[<Property>]
let ``Test Three`` () =
Prop.forAll (NeverAOne.Data ()) (fun x -> x.value = 1)

F# Cannot enumerate sequence generated by yield when using GetEnumerator

The following example is based on a snippet that produces functions that allow enumerating sequence values one by one.
Here printAreEqual () gives true, print2 () gives 12345678910, but print1 () gives 0000000000.
Why cannot the function returned by enumerate return the values of the sequence generated using yield?
open System.Linq
let enumerate (xs: seq<_>) =
use en = xs.GetEnumerator()
fun () ->
en.MoveNext() |> ignore
en.Current
let s1 = seq { for i in 1 .. 10 do yield i }
let s2 = seq { 1 .. 10 }
let f1 = s1 |> enumerate
let f2 = s2 |> enumerate
let printAreEqual () = Enumerable.SequenceEqual (s1, s2) |> printf "%b" // true
let print1 () = for i in 1 .. 10 do f1() |> printf "%i" // 0000000000
let print2 () = for i in 1 .. 10 do f2() |> printf "%i" // 12345678910
The use en = ... in the enumerate function is effectively doing this:
let enumerate (xs: seq<_>) =
let en = xs.GetEnumerator()
let f =
fun () ->
en.MoveNext() |> ignore
en.Current
en.Dispose()
f
You're always disposing of the enumerator before you start using it, so the behaviour is probably undefined in this situation and it doesn't matter why you get different results for two sequences with different implementations.
Fine-grained control of sequence enumeration is always tricky and it's hard to make helper functions for because of the mutable state.

Alternative approach to avoid "Incomplete pattern match" warning

I have written a function that takes an array as input and returns an array of equal size as output. For example:
myFunc [| "apple"; "orange"; "banana" |]
> val it : (string * string) [] =
[|("red", "sphere"); ("orange", "sphere"); ("yellow", "oblong")|]
Now I want to assign the results via a let binding. For example:
let [|
( appleColor, appleShape );
( orangeColor, orangeShape );
( bananaColor, bananaShape )
|] =
myFunc [| "apple"; "orange"; "banana" |]
Which works great...
> val orangeShape : string = "sphere"
> val orangeColor : string = "orange"
> val bananaShape : string = "oblong"
> val bananaColor : string = "yellow"
> val appleShape : string = "sphere"
> val appleColor : string = "red"
...except it produces a warning:
warning FS0025: Incomplete pattern matches on this expression. For example, the value '[|_; _; _; _|]' may indicate a case not covered by the pattern(s).
The source and reason for the warning has already been covered, I'm just looking for a succinct work-around. This function call occurs near the top of my function, and I don't like the idea of putting the entire function body inside a match:
let otherFunc =
match myFunc [| "apple"; "orange"; "banana" |] with
| [|
( appleColor, appleShape );
( orangeColor, orangeShape );
( bananaColor, bananaShape )
|] ->
// ... the rest of my function logic
| _ -> failwith "Something impossible just happened!"
That just smells bad. I don't like the idea of ignoring the warning either - goes against my better judgment. Are there any other options open to me, or do I just need to find a different approach entirely?
One possibility if you expect this kind of calling pattern to be frequent is to make wrappers that act on the sizes of tuples you expect, e.g.
myFunc3 (in1,in2,in3) =
match myFunc [|in1;in2;in3|] with
[|out1;out2;out3|] -> out1, out2, out3
_ -> failwith "Internal error"
etc. But all it does is move the ugly code to a standard place, and writing out the wrappers will be inconvenient.
I don't think there's any better option with this API, because there's no way to tell the compiler that myFunc always returns the same number of elements it is passed.
Another option might be to replace myFunc with an IDisposable class:
type MyClass() =
let expensiveResource = ...
member this.MyFunc(v) = ...calculate something with v using expensiveResource
interface IDisposable with
override this.Dispose() = // cleanup resource
and then use it in a block like
use myClass = new MyClass()
let appleColor, appleShape = myClass.MyFunc(apple)
...
Adapting #Ganesh's answer, here's a primitive way to approach the problem:
let Tuple2Map f (u, v)
= (f u, f v)
let Tuple3Map f (u, v, w)
= (f u, f v, f w)
let Tuple4Map f (u, v, w, x)
= (f u, f v, f w, f x)
Example:
let Square x = x * x
let (a,b) = Tuple2Map Square (4,6)
// Output:
// val b : int = 36
// val a : int = 16
But I guess something even more primitive would be this:
let Square x = x * x
let (a,b) = (Square 4, Square 6)
And if the function name is too long, e.g.
// Really wordy way to assign to (a,b)
let FunctionWithLotsOfInput w x y z = w * x * y * z
let (a,b) =
(FunctionWithLotsOfInput input1 input2 input3 input4A,
FunctionWithLotsOfInput input1 input2 input3 input4B)
We can define temporary function
let FunctionWithLotsOfInput w x y z = w * x * y * z
// Partially applied function, temporary function
let (a,b) =
let f = (FunctionWithLotsOfInput input1 input2 input3)
(f input4A, f input4B)

Recursively update a State Monad

this question is related to this question
I have a state monad. An object provides an update function as in the OOD strategy pattern.
The choice of having a object is that in real, production code, the
class provides an array of operations, all sharing state through the
monad. Inheritance helped me extend the basic functionality and
further customizing the class providing the operations.
The choice of having a monad instead of a mutable property within the class is that the monad, through proper use of generics, is helping me abstracting and being more flexible on what variables/information must be carried along the computation as "state".
I have a simple toy example:
/////////////////////////////////////////////////////////////////////////////////////
// Definition of the state
/////////////////////////////////////////////////////////////////////////////////////
type StateFunc<'State, 'T> = 'State -> 'T * 'State
/////////////////////////////////////////////////////////////////////////////////////
// Definition of the State monad type
/////////////////////////////////////////////////////////////////////////////////////
type StateMonadBuilder<'State>() =
// M<'T> -> M<'T>
member b.ReturnFrom a : StateFunc<'State, 'T> = a
// 'T -> M<'T>
member b.Return a : StateFunc<'State, 'T> = ( fun s -> a, s)
// M<'T> * ('T -> M<'U>) -> M<'U>
member b.Bind(p : StateFunc<_, 'T>, rest : 'T -> StateFunc<_,_>) : StateFunc<'State, 'U> =
(fun s ->
let a, s' = p s
rest a s')
// Getter for the whole state, this type signature is because it passes along the state & returns the state
member b.getState : StateFunc<'State, _> = (fun s -> s, s)
// Setter for the state
member b.putState (s:'State) : StateFunc<'State, _> = (fun _ -> (), s)
let runState f init = f init
/////////////////////////////////////////////////////////////////////////////////////
// STRATEGY PATTERN
/////////////////////////////////////////////////////////////////////////////////////
let state = StateMonadBuilder<int> ()
// DoubleFunctOne defines standard operations that remain always the same
type Strategy (aFunction) =
member this.Update (x: int) = state {
let! currState = state.getState
let processedx = aFunction x
do! state.putState (currState + x) }
// Create a function that customizes the strategy
let myFunction x =
2 * x
// Customize the strategy with the desired function:
let strategy = Strategy (myFunction)
/////////////////////////////////////////////////////////////////////////////////////////////////////////
// Update recursively
/////////////////////////////////////////////////////////////////////////////////////////////////////////
// ?? How to run update recursively ??
let result initialCondition =
initialCondition
|> (for i = 10 to 100 do
yield state { do! strategy.Update i } )
My goal is to apply the initial conditions, fetch data and launch recursively (within a for or a while loop or even some functional operation) the functions provided by strategy. Working with the monad, I am not sure how to do this.
Thank you.
Computational Expression For
Inspired by #kvb answer, I have added a for method to the computational expression.
// Loops through seqnc of numbers that constitute an input to func
member b.For (seqnc:_ List, func) =
seqnc
|> List.map (fun item -> func item)
|> List.reduce (fun acc item ->
(fun s ->
let _, s' = acc s
item s' ) )
I run a few tests and I have the impression that this one works.
Thanks.
Something like this?
let result initialCondition =
let rec loop = function
| 101 -> state { return () }
| i ->
state {
do! strategy.Update i
do! loop (i+1)
}
initialCondition
|> runState (loop 10)
Alternatively, define a For member on your builder and write it the more imperative way:
let result initialCondition =
let f = state {
for i in 10 to 100 do
do! strategy.Update i
}
initialCondition
|> runState f
Also, note that there is likely a bug in your definition of Strategy.Update: processedx is bound but unused.

F# compose pattern matched function

I have these types:
type ShouldRetry = ShouldRetry of (RetryCount * LastException -> bool * RetryDelay)
and RetryCount = int
and LastException = exn
and RetryDelay = TimeSpan
type RetryPolicy = RetryPolicy of ShouldRetry
Now I want composability of the retries; something like this:
let serverOverloaded = [| exnRetry<TimeoutException>;
exnRetry<ServerBusyException> |]
|> Array.map (fun fn -> fn (TimeSpan.FromSeconds(4.0)))
let badNetwork = [||] // etc
let compose p1 p2 =
// http://fssnip.net/7h
RetryPolicy(ShouldRetry( (fun (c,e) ->
let RetryPolicy(ShouldRetry(fn)) = p1
let RetryPolicy(ShouldRetry(fn')) = p2
let (cont, delay) = fn c,e
if cont then cont, delay
else
let (cont', delay') = fn' c,e
cont', delay') ))
let finalPolicy = serverOverloaded |> Array.scan compose (RetryPolicies.NoRetry())
But I'm getting compiler errors on fn, delay and fn', saying "The value or constructor 'fn' is not defined".
I can see two problems in your compose function.
When decomposing p1 and p2, the pattern needs to be wrapped in parentheses (otherwise, the compiler interprets the code as a definition of RetryPolicy function, instead of pattern matching):
let (RetryPolicy(ShouldRetry(fn))) = p1
let (RetryPolicy(ShouldRetry(fn'))) = p2
When calling fn' a bit later, you need to pass it the arguments in a tuple (otherwise, the compiler thinks that you're calling fn' with just a single argument c and then building a tuple):
let (cont', delay') = fn' (c,e)
I didn't check (or tried to run) the whole example, so I don't know if the rest of the code does what you want.

Resources