How do you express (Keys.Control | Keys.M) in F#? - f#

In C#, you can express characters for the KeyPress event in the form Keys.Control | Keys.M. In F#, Keys.Control ||| Keys.M doesn't work. What does?
Edit: Interesting indeed. Using System.Windows.Forms.Keys.Control ||| System.Windows.Forms.Keys.M as per Johannes Rössel's suggestion below in the F# interactive window works exactly as he shows. Writing it in a .fs file:
form.KeyPress.Add (fun e ->
if (e.KeyChar = (System.Windows.Forms.Keys.Control ||| System.Windows.Forms.Keys.M)) then textbox.SelectAll() )
gives me the error The type 'char' does not support any operators named '|||'. So I probably misidentified the location of the problem. There is no typecasting from Keys to char.

Just little addition to Johaness Rössel's answer, there is nicer (or 'more functional') way to do this using reactive programming.
form.KeyDown
|> Event.filter (fun e -> e.KeyData = (Keys.Control + Keys.M))
|> Event.map (fun _ -> textbox.SelectAll())
|> ignore

Use +:
Keys.Control + Keys.M
FWIW, ||| works for me, though:
> System.Windows.Forms.Keys.Control ||| System.Windows.Forms.Keys.M;;
val it : System.Windows.Forms.Keys = M, Control

Related

F#: shortest way to convert a string option to a string

The objective is to convert a string option that comes out of some nicely typed computation to a plain string that can then be passed to the UI/printf/URL/other things that just want a string and know nothing of option types. None should just become the empty string.
The obvious way is to do a match or an if on the input:
input |> fun s -> fun s -> match s with | Some v -> v | _ -> "" or
input |> fun s -> if s.IsSome then s.Value else ""
but while still being one-liners, these still take up quite a lot of line space. I was hoping to find the shortest possible method for doing this.
You can also use the function defaultArg input "" which in your code that uses forward pipe would be:
input |> fun s -> defaultArg s ""
Here's another way of writing the same but without the lambda:
input |> defaultArg <| ""
It would be better if we had a version in the F# core with the arguments flipped. Still I think this is the shortest way without relaying in other libraries or user defined functions.
UPDATE
Now in F# 4.1 FSharp.Core provides Option.defaultValue which is the same but with arguments flipped, so now you can simply write:
Option.defaultValue "" input
Which is pipe-forward friendly:
input |> Option.defaultValue ""
The obvious way is to write yourself a function to do it, and if you put it in an Option module, you won't even notice it's not part of the core library:
module Option =
let defaultTo defValue opt =
match opt with
| Some x -> x
| None -> defValue
Then use it like this:
input |> Option.defaultTo ""
The NuGet package FSharpX.Extras has Option.getOrElse which can be composed nicely.
let x = stringOption |> Option.getOrElse ""
The best solution I found so far is input |> Option.fold (+) "".
...which is just a shortened version of input |> Option.fold (fun s t -> s + t) "".
I suspect that it's the shortest I'll get, but I'd like to hear if there are other short ways of doing this that would be easier to understand by non-functional programmers.

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 []

Right associative operator in F# [duplicate]

This question already has an answer here:
Function Application Operator ($) in F#?
(1 answer)
Closed 8 years ago.
Sometimes I have to write:
myList |> List.iter (fun x -> x)
I would really like to avoid the parentheses. In Haskell there is an operator for this ($)
It would look like this
myList |> List.iter $ fun x -> x
I created a custom operator
let inline (^!) f a = f a
and now I can write it like this
myList |> List.iter ^! fun x -> x
Is there something like this in F#?
There is no way to define custom operator with an explicitly specified associativity in F# - the associativity is determined based on the symbols forming the operator (and you can find it in the MSDN documentation for operators).
In this case, F# does not have any built-in operator that would let you avoid the parentheses and the idiomatic way is to write the code as you write it originally, with parentheses:
myList |> List.iter (fun x -> x)
This is difference in style if you are coming from Haskell, but I do not see any real disadvantage of writing the parentheses - it is just a matter of style that you'll get used to after writing F# for some time. If you want to avoid parentheses (e.g. to write a nice DSL), then you can always named function and write something like:
myList |> List.iter id
(I understand that your example is really just an example, so id would not work for your real use case, but you can always define your own functions if that makes the code more readable).
No, there's nothing like this in a standard F# library. However, you have almost done creating your own operator (by figuring out its name must start with ^).
This snippet by Stephen Swensen demonstrates a high precedence, right associative backward pipe, (^<|).
let inline (^<|) f a = f a
This single-liner from the linked page demonstrates how to use it:
{1..10} |> Seq.map ^<| fun x -> x + 3
And here is an example how to use it for multi-line functions. I find it most useful for real-world multi-liners as you no longer need to keep closing parenthesis at the end:
myList
|> List.map
^<| fun x ->
let ...
returnValue
In F# it's <|
So it would look like:
myList |> List.iter <| fun x -> x

Convert a list of characters (or array) to a string

how does one convert from a list of characters to a string?
To put it another way, how do I reverse List.ofSeq "abcd"?
UPDATE: new System.String (List.ofSeq "abcd" |> List.toArray) |> printfn "%A" seems to work fine, with or without new, but List.ofSeq "abcd" |> List.toArray) |> new System.String |> printfn "%A" fails. Why?
I asked a similar question once before. It seems object constructors aren't composable so you can't pass them as a function.
List.ofSeq "abcd" |> List.toArray |> (fun s -> System.String s) |> printfn "%A"
List.ofSeq "abcd" |> List.toArray |> (fun s -> new System.String(s)) |> printfn "%A"
Update
Constructors are first-class functions as of F# 4.0
List.ofSeq "abcd" |> List.toArray |> System.String |> printfn "%A"
Working with strings in F# is sometimes a bit uncomfortable. I would probably use the same code as Dario. The F# grammar doesn't allow using constructors as first class functions, so you unfortunately cannot do the whole processing in a single pipeline. In general, you can use static members and instance methods as first class functions, but not instance properties or constructors.
Anyway, there is a really nasty trick you can use to turn a constructor into a function value. I would not recommend actually using it, but I was quite surprised to see that it actually works, so I thought it may be worth sharing it:
let inline ctor< ^R, ^T
when ^R : (static member ``.ctor`` : ^T -> ^R)> (arg:^T) =
(^R : (static member ``.ctor`` : ^T -> ^R) arg)
This defines a function that will be inlined at compile time, which requires that the first type parameter has a constructor that takes a value of the second type parameter. This is specified as a compile-time constraint (because .NET generics cannot express this). Also, F# doesn't allow you to specify this using the usual syntax for specifying constructor constraints (which must take unit as the argument), but you can use the compiled name of constructors. Now you can write for example:
// just like 'new System.Random(10)'
let rnd = ctor<System.Random, _> 10
rnd.Next(10)
And you can also use the result of ctor as first-class function:
let chars = [ 'a'; 'b'; 'c' ]
let str = chars |> Array.ofSeq |> ctor<System.String, _>
As I said, I think this is mainly a curiosity, but a pretty interesting one :-).
Your approach:
new System.String (listOfChars |> List.toArray)
is the solution I usually end up with too.
F#'s grammar/type inference system simply seems unable to recognize a .NET constructor like new String as a curried function (which prevents you from using pipelining).
Just faced similar problem, and came up with this solutions:
List.fold (fun str x -> str + x.ToString()) "" (List.ofSeq "abcd")

Resources