Nested monad binding in F# - f#

Trying to wrap my mushy head around monads and binding
Take this snippet for example, purely as a learning excersise
open FSharpPlus
open FSharpPlus.Data
let lowerBounds i =
if i > 10 then
Ok i
else
Error "i was <= 10"
let upperBounds i =
if i < 20 then
Ok i
else
Error "i was >= 20"
let even i =
if i % 2 = 0 then
Ok i
else
Error "i was uneven"
let rebind validation x = x >>= validation |> Seq.singleton
seq{10..20} |> Seq.map lowerBounds
>>= rebind upperBounds
>>= rebind even
Whilst this executes, I don't like the rebind function as it is not generic, and tied to Seq.singleton, not to mention I can't see how to make it point free (but that's a minor.....point)
Now I know I could pass in the dependencies, or totally refactor things and compose the validation functions, but I trying to learn how to bind to the nested monad. (Something like a recursive >>= infix operator ??) which feels like it would be the more FPish approach ?
As you can see I'm using FSharpPlus, and I had a look at the monad transformer section but I don't know even if that is what I should be looking at ?

You can use the Kleisli composition:
seq{10..20} |> Seq.map ( lowerBounds >=> upperBounds >=> even)

Related

Using bind and Kliesli composition operators with Result

I'm trying to use the bind (>>=) and Kleisli composition (>=>) operators with the basic Result type, but either they are not defined or are not in scope:
let f x =
if x%2 = 0 then Ok (x/2)
else Error ()
let ff x = Ok x >>= f >>= f
let ff' = f >=> f
[<EntryPoint>]
let main _ =
printfn "%A" (ff 12)
printfn "%A" (ff' 28)
0
Error FS0043 Expecting a type supporting the operator '>>=' but given a function type. You may be missing an argument to a function.
I've tried to open a few different namespaces to bring the definition into scope, but no luck.
It seems from this like the operators can't be defined in general without extensions, but are there definitions for the standard Result anywhere?
Haskell-like operators are not defined in the F# core library, nor are they likely to ever be. You'll need to either write them in your own prelude, or use a library like FSharpPlus for these and other more Haskell-like (Well, typelevel) programming approaches.
In addition to what Phillip said in his answer, it might be useful to add that you can rewrite your example using the built-in Result.bind operation and function composition or piping:
let f x =
if x%2 = 0 then Ok (x/2)
else Error ()
let ff x = Ok x |> Result.bind f |> Result.bind f
let ff' = f >> Result.bind f
printfn "%A" (ff 12)
printfn "%A" (ff' 28)
This is of course just a toy example, so it's hard to say what you actually want to do, but if I was trying to use Result, my first choice would be to use the standard library functions - they may make your code longer, but it is arguably more readable.

Is there a built-in F# function to perform a side-effect on an item and return the item [duplicate]

...or in FSharpx?
let tee sideEffect =
fun x ->
do sideEffect x
x
The usage could be something like
f >> tee (printfn "F returned: %A") >> g >> h
Or is there another simple way to do this?
thanks!
The closest I've seen is actually in WebSharper. The definition is:
let inline ( |>! ) x sideEffect =
do sideEffect x
x
Usage:
(x |>! printf "%A") |> nextFunc
ExtCore includes a function called tap which does exactly what you want. I use it for primarily for inspecting intermediate values within an F# "pipeline" (hence the name).
For example:
[| 1;2;3 |]
|> Array.map (fun x -> x * 2)
|> tap (fun arr ->
printfn "The mapped array values are: %A" arr)
|> doOtherStuffWithArray
As far as I know, a function like this isn't defined anywhere in the F# core library - though the library is missing many standard functions that are quite easy to define yourself, so my recommendation would be just to add it somewhere in your project - your tee seems like the best way to go.
That said, I'd probably prefer using less declarative style if I need side-effects and write something like:
let fResult = f fInput
printfn "F returned: %A" fResult
fResult |> g |> h
This is just a matter of style, but I prefer declarative style for fully declarative code and imperative style when there are side-effects involved. As a bonus, using local variables makes debugging easier. But using a function like tee is an equally good alternative that many people in the F# community would prefer.

Avoid mutation in this example in F#

Coming from an OO background, I am having trouble wrapping my head around how to solve simple issues with FP when trying to avoid mutation.
let mutable run = true
let player1List = ["he"; "ho"; "ha"]
let addValue lst value =
value :: lst
while run do
let input = Console.ReadLine()
addValue player1List input |> printfn "%A"
if player1List.Length > 5 then
run <- false
printfn "all done" // daz never gunna happen
I know it is ok to use mutation in certain cases, but I am trying to train myself to avoid mutation as the default. With that said, can someone please show me an example of the above w/o using mutation in F#?
The final result should be that player1List continues to grow until the length of items are 6, then exit and print 'all done'
The easiest way is to use recursion
open System
let rec makelist l =
match l |> List.length with
|6 -> printfn "all done"; l
| _ -> makelist ((Console.ReadLine())::l)
makelist []
I also removed some the addValue function as it is far more idiomatic to just use :: in typical F# code.
Your original code also has a common problem for new F# coders that you use run = false when you wanted run <- false. In F#, = is always for comparison. The compiler does actually warn about this.
As others already explained, you can rewrite imperative loops using recursion. This is useful because it is an approach that always works and is quite fundamental to functional programming.
Alternatively, F# provides a rich set of library functions for working with collections, which can actually nicely express the logic that you need. So, you could write something like:
let player1List = ["he"; "ho"; "ha"]
let player2List = Seq.initInfinite (fun _ -> Console.ReadLine())
let listOf6 = Seq.append player1List list2 |> Seq.take 6 |> List.ofSeq
The idea here is that you create an infinite lazy sequence that reads inputs from the console, append it at the end of your initial player1List and then take first 6 elements.
Depending on what your actual logic is, you might do this a bit differently, but the nice thing is that this is probably closer to the logic that you want to implement...
In F#, we use recursion to do loop. However, if you know how many times you need to iterate, you could use F# List.fold like this to hide the recursion implementation.
[1..6] |> List.fold (fun acc _ -> Console.ReadLine()::acc) []
I would remove the pipe from match for readability but use it in the last expression to avoid extra brackets:
open System
let rec makelist l =
match List.length l with
| 6 -> printfn "all done"; l
| _ -> Console.ReadLine()::l |> makelist
makelist []

Composing 2 (or n) ('a -> unit) functions with same arg type

Is there some form of built-in / term I don't know that kinda-but-its-different 'composes' two 'a -> unit functions to yield a single one; e.g.:
let project event =
event |> logDirections
event |> stashDirections
let dispatch (batch:EncodedEventBatch) =
batch.chooseOfUnion () |> Seq.iter project
might become:
let project = logDirections FOLLOWEDBY stashDirections
let dispatch (batch:EncodedEventBatch) =
batch.chooseOfUnion () |> Seq.iter project
and then:
let dispatch (batch:EncodedEventBatch) =
batch.chooseOfUnion () |> Seq.iter (logDirections FOLLOWEDBY stashDirections)
I guess one might compare it to tee (as alluded to in FSFFAP's Railway Oriented Programming series).
(it needs to pass the same arg to both and I'm seeking to run them sequentially without any exception handling trickery concerns etc.)
(I know I can do let project fs arg = fs |> Seq.iter (fun f -> f arg) but am wondering if there is something built-in and/or some form of composition lib I'm not aware of)
The apply function from Klark is the most straightforward way to solve the problem.
If you want to dig deeper and understand the concept more generally, then you can say that you are lifting the sequential composition operation from working on values to work on functions.
First of all, the ; construct in F# can be viewed as sequential composition operator. Sadly, you cannot quite use it as one, e.g. (;) (because it is special and lazy in the second argument) but we can define our own operator instead to explore the idea:
let ($) a b = a; b
So, printfn "hi" $ 1 is now a sequential composition of a side-effecting operation and some expression that evaluates to 1 and it does the same thing as printfn "hi"; 1.
The next step is to define a lifting operation that turns a binary operator working on values to a binary operator working on functions:
let lift op g h = (fun a -> op (g a) (h a))
Rather than writing e.g. fun x -> foo x + bar x, you can now write lift (+) foo bar. So you have a point-free way of writing the same thing - just using operation that works on functions.
Now you can achieve what you want using the lift function and the sequential composition operator:
let seq2 a b = lift ($) a b
let seq3 a b c = lift ($) (lift ($) a b) c
let seqN l = Seq.reduce (lift ($)) l
The seq2 and seq3 functions compose just two operations, while seqN does the same thing as Klark's apply function.
It should be said that I'm writing this answer not because I think it is useful to implement things in F# in this way, but as you mentioned railway oriented programming and asked for deeper concepts behind this, it is interesting to see how things can be composed in functional languages.
Can you just apply an array of functions to a given data?
E.g. you can define:
let apply (arg:'a) (fs:(('a->unit) seq)) = fs |> Seq.iter (fun f -> f arg)
Then you will be able to do something like this:
apply 1 [(fun x -> printfn "%d" (x + 1)); (fun y -> printfn "%d" (y + 2))]

Return item at position x in a list

I was reading this post While or Tail Recursion in F#, what to use when? were several people say that the 'functional way' of doing things is by using maps/folds and higher order functions instead of recursing and looping.
I have this function that returns the item at position x in a list:
let rec getPos l c = if c = 0 then List.head l else getPos (List.tail l) (c - 1)
how can it be converted to be more functional?
This is a primitive list function (also known as List.nth).
It is okay to use recursion, especially when creating the basic building blocks. Although it would be nicer with pattern matching instead of if-else, like this:
let rec getPos l c =
match l with
| h::_ when c = 0 -> h
| _::t -> getPos t (c-1)
| [] -> failwith "list too short"
It is possible to express this function with List.fold, however the result is less clear than the recursive version.
I'm not sure what you mean by more functional.
Are you rolling this yourself as a learning exercise?
If not, you could just try this:
> let mylist = [1;2;3;4];;
> let n = 2;;
> mylist.[n];;
Your definition is already pretty functional since it uses a tail-recursive function instead of an imperative loop construct. However, it also looks like something a Scheme programmer might have written because you're using head and tail.
I suspect you're really asking how to write it in a more idiomatic ML style. The answer is to use pattern matching:
let rec getPos list n =
match list with
| hd::tl ->
if n = 0 then hd
else getPos tl (n - 1)
| [] -> failWith "Index out of range."
The recursion on the structure of the list is now revealed in the code. You also get a warning if the pattern matching is non-exhaustive so you're forced to deal with the index too big error.
You're right that functional programming also encourages the use of combinators like map or fold (so called points-free style). But too much of it just leads to unreadable code. I don't think it's warranted in this case.
Of course, Benjol is right, in practice you would just write mylist.[n].
If you'd like to use high-order functions for this, you could do:
let nth n = Seq.take (n+1) >> Seq.fold (fun _ x -> Some x) None
let nth n = Seq.take (n+1) >> Seq.reduce (fun _ x -> x)
But the idea is really to have basic constructions and combine them build whatever you want. Getting the nth element of a sequence is clearly a basic block that you should use. If you want the nth item, as Benjol mentioned, do myList.[n].
For building basic constructions, there's nothing wrong to use recursion or mutable loops (and often, you have to do it this way).
Not as a practical solution, but as an exercise, here is one of the ways to express nth via foldr or, in F# terms, List.foldBack:
let myNth n xs =
let step e f = function |0 -> e |n -> f (n-1)
let error _ = failwith "List is too short"
List.foldBack step xs error n

Resources