Choice type in F# - f#

I'm getting some error with choice constructs, need help in fixing the code.
The error is
The 'if' expression needs to have type 'Choice' to satisfy context type requirements. It currently has type 'bool'.
let safeDiv num den : Choice<string, bool> =
if den = 0. then
Choice1Of2 = "divide by zero"
else
Choice2Of2 = (num/den)
printfn "%s" (safeDiv 15. 3.).Choice1Of2

Your Choice has string and float, not string and bool.
let safeDiv num den : Choice<string, float> =
Choice1Of2 and Choice2Of2 are constructors, so you should not use =. (Why do you use =? I cannot understand)
if den = 0. then
Choice1Of2 "divide by zero"
else
Choice2Of2 (num / den)
Then, you should pattern-match to print the content of Choice.
match safeDiv 15. 3. with
| Choice1Of2 msg -> printfn "%s" msg
| Choice2Of2 x -> printfn "%f" x
(live example)

Related

Need Help on Translating C# to F#

I need help on translating custom extension for IndexOfAny for string as existing framework does not have IndexOfAny that matching string values. Already translated my own. However I have no idea how to break out of loop by return value. Any idea how to break out of loop or better solution.
Below is my translation.
C#
public static int IndexOfAnyCSharp(this string str, string[] anyOff) {
if (str != null && anyOff != null)
foreach (string value in anyOff) {
int index = str.IndexOf(value);
if (index > -1) return index;
}
return -1;
}
F#
[<Extension>]
static member public IndexOfAnyFSharp(str:string, anyOff:string[]) =
match str <> null && anyOff <> null with
| true ->
let mutable index = -1
for value in anyOff do
if index = -1 then
index <- str.IndexOf(value)
index
| false -> -1
Seq.tryFind is your friend. A basic building block would be something like
let IndexOfAny (s: string, manyStrings: string seq) =
manyStrings
|> Seq.map (fun m -> s.IndexOf m)
|> Seq.tryFind (fun index -> index >= 0)
This will return None if nothing matches - this is more idiomatic F# than returning -1: The compiler will force you to think about the case that nothing matches.
Update: You may prefer:
let IndexOfAny (s: string, manyStrings: string seq) =
manyStrings
|> Seq.tryPick (fun m ->
match s.IndexOf m with
| -1 -> None
| i -> Some i
)
Using Seq.tryFind or Array.tryFind is idiomatic F# but also has different performance characteristics than the C# loop. Especially Seq module is problematic when it comes to performance and memory overhead. This can sometimes be of importance.
As others noted in F# you can't exit early from a for loop. I used to be bothered about that but no longer am as F# supports tail call elimination that allow us to implement the loop as a tail recursive function.
Below is an example on how to use tail recursion. The code below should perform roughly similar to the C# loop. I don't exactly implement the semantics of the C# in that I return an Result<int*int, Unit> instead. I use Result over option because Result doesn't add GC pressure as it's a struct type.
Also included is a neat way IMO to protect F# code from the dangers of null values.
// If our function is callable from C# we can use active patterns as a neat way to protect our
// F# code from null values
// Functions that are only callable from F# code we don't need to protect as long as we protect
// the entry points
let inline (|DefaultTo|) dv v = if System.Object.ReferenceEquals (v, null) then dv else v
let inline (|NotNull|) v = if System.Object.ReferenceEquals (v, null) then raise (System.NullReferenceException ()) else v
let emptySet : string [] = [||]
let indexOfSet (DefaultTo "" str) (DefaultTo emptySet set) : Result<int*int, unit> =
// In F# tail recursion is used as a more powerful looping construct
// F# suppports tail call elimination meaning under the hood this is
// implemented as an efficient loop
// Note: I pass str and set as argument in order to make F# doesn't
// create new lambda object that closes over them (reduces GC load)
let rec loop (str : string) (set : string []) i =
if i < set.Length then
let index = str.IndexOf set.[i]
if index = -1 then loop str set (i + 1)
else Ok (i, index)
else
Error ()
loop str set 0
printfn "%A" <| indexOfSet null null
printfn "%A" <| indexOfSet null [| "abc"; "ab"; "a" |]
printfn "%A" <| indexOfSet "" [| "abc"; "ab"; "a" |]
printfn "%A" <| indexOfSet "a" [| "abc"; "ab"; "a" |]
printfn "%A" <| indexOfSet "ab" [| "abc"; "ab"; "a" |]
printfn "%A" <| indexOfSet "abc" [| "abc"; "ab"; "a" |]
printfn "%A" <| indexOfSet "da" [| "abc"; "ab"; "a" |]
printfn "%A" <| indexOfSet "dab" [| "abc"; "ab"; "a" |]
printfn "%A" <| indexOfSet "dabc" [| "abc"; "ab"; "a" |]

F# Monad multiple parameters

I am trying to wrap my head around monads and how to use them in real world examples. The first "task" i set myself is to write an "Exception Monad" which of course (at this point) is nothing more than the "Either monad" twisted to suit my purpose.
My code looks like this:
type MException<'a> =
| Success of 'a
| Failure of string
with
static member returnM a =
Success a
static member bind f =
fun e ->
match e with
| Success a -> f a
| Failure m -> Failure m
static member map f =
fun e ->
match e with
| Success a -> Success (f a)
| Failure m -> Failure m
// Create a little test case to test my code
let divide (n, m) =
match m with
| 0 -> Failure "Cannot divide by zero"
| _ -> Success ((float n) / (float m))
let round (f:float) =
Success ( System.Math.Round(f, 3) )
let toString (f:float) =
sprintf "%f" f
let divideRoundAndPrintNumber =
divide
>> MException<_>.bind round
>> MException<_>.map toString
// write the result
let result = divideRoundAndPrintNumber (11, 3)
match result with
| Success r -> printf "%s\n" r
| Failure m -> printf "%s\n" m
My question is the following: the divide function now takes a tuple. What can or should I do to make the bind and map functions behave correctly for functions with multiple parameters?
EDIT 30-12-2015:
Both the answers and comments of #Mark Seemann helped find the answer to the problem. #Mikhail provided the implementation of the solution. Currying is the right way of solving the problem. Computation Expressions are not a solution but a syntax abstraction which does work but gets complicated once you add async and other patterns to the problem. "Simple" composition seems like the easiest and "trueest" solution.
Change divideRoundAndPrintNumber to be a function instead of a value
let divide n m =
match m with
| 0 -> Failure "Cannot divide by zero"
| _ -> Success ((float n) / (float m))
let divideRoundAndPrintNumber n =
divide n
>> MException<_>.bind round
>> MException<_>.map toString
Unfortunately I do not know enough about F# to understand your code completely. For example I do not understand the >> operator and the MException<_> expression. But I can give you an alternative solution for your problem. It utilzies a F# feature called "Computation Expressions". It enables you to do "Monadic" magic in a nice F#-like way:
type MException<'a> =
| Success of 'a
| Failure of string
type ExceptionBuilder() =
member this.Bind (m, f) =
match m with
| Success a -> f a
| Failure m -> Failure m
member this.Return (x) =
Success (x)
let ex = new ExceptionBuilder()
let divide n m =
if m = 0 then Failure "Cannot divide by zero"
else Success ((float n)/(float m))
let round (f : float) =
Success (System.Math.Round(f, 3))
let divideRoundAndPrintNumber a b =
ex {
let! c = divide a b
let! d = round c
printf "result of divideRoundAndPrintNumber: %f\n" d
return d
}
let result = divideRoundAndPrintNumber 11 0
match result with
| Success r -> printf "%f\n" r
| Failure m -> printf "%s\n" m
Apologies when my answer does not match your question completely but I hope it helps.
Here you can find an excellent blog post series about this topic:
http://fsharpforfunandprofit.com/posts/computation-expressions-intro/
I also found this article very enlightening:
http://adit.io/posts/2013-04-17-functors,_applicatives,_and_monads_in_pictures.html
Monads have a fairly strict required structure, they must have:
Return: 'a -> m<'a>
and
Bind: m<'a> -> ('a -> m<'b>) -> m<'b>
Your divide function has the signature int*int -> MException<float>, i.e. it does indeed have the required 'a -> m<'b> form to be used with bind. When used with bind, it would act on something of type MException<int*int> and produce an MException<float>.
If divide is instead of type int -> int -> MException<float> (i.e. 'a -> 'b -> m<'c>'), we can't use it with bind directly. What we can do is unwrap the tuple and then supply the arguments one by one to create a lambda that does have the right form.
Let's add an extra Return so that we can see more clearly some different approaches for handling functions within these constraints:
let divideTupled (n, m) =
match m with
| 0 -> Failure "Cannot divide by zero"
| _ -> Success ((float n) / (float m))
let divideRoundAndPrintNumber n m =
MException<_>.Return (n,m)
|> MException<_>.Bind divideTupled
|> MException<_>.Bind round
|> MException<_>.Map toString
or
let divideCurried n m =
match m with
| 0 -> Failure "Cannot divide by zero"
| _ -> Success ((float n) / (float m))
let divideRoundAndPrintNumber n m =
MException<_>.Return (n,m)
|> MException<_>.Bind (fun (n,m) -> divideCurried n m)
|> MException<_>.Bind round
|> MException<_>.Map toString
Computation expressions, as mentioned by Olaf, provide some nice syntactic sugar for working with monads in F#.
Why not define divide like you normally would?
let divide n m =
match m with
| 0 -> Failure "Cannot divide by zero"
| _ -> Success ((float n) / (float m))
You could then define divideRoundAndPrintNumber like this, likewise in curried form:
let divideRoundAndPrintNumber n m =
divide n m
|> MException<_>.bind round
|> MException<_>.map toString
FSI ad-hoc tests:
> let result = divideRoundAndPrintNumber 11 3;;
val result : MException<string> = Success "3.667000"
> let result = divideRoundAndPrintNumber 11 0;;
val result : MException<string> = Failure "Cannot divide by zero"

Simple closure function

I have following code
let f2 x:int =
fun s:string ->
match x with
| x when x > 0 -> printfn "%s" s
| _ -> printfn "%s" "Please give me a number that is greater than 0"
And the compiler complain:
Unexpected symbol ':' in lambda expression. Expected '->' or other token.
What am I doing wrong?
You have to put parentheses around your type annotations:
let f2 (x : int) =
fun (s : string) ->
match x with
| x when x > 0 -> printfn "%s" s
| _ -> printfn "%s" "Please give me a number that is greater than 0"
Also be aware if you omit the parentheses around x like in your example, this would mean the function f2 returns an int, not constrain the type of x to be int.
Update for the comment:
Why if I omit the parentheses around x, this would mean the function f2 returns an int?
Because that is how you specify the return type of functions.
What would be this in C#:
ReturnTypeOfFunction functionName(TypeOfParam1 firstParam, TypeOfParam2 secondParam) { ... }
would look like this in F#:
let functionName (firstParam : TypeOfParam1) (secondParam : TypeOfParam2) : ReturnTypeOfFunction =
// Function implementation that returns object of type ReturnTypeOfFunction
A more detailed explanation can be found on MSDN.
You have two instances of the same problem. When defining a function, putting :*type* at the end of the signature indicates that the function returns that type. In this case you're indicating that you have a function f2 which takes a parameter and returns an int. To fix it you need to put parenthesis around the annotation. That syntax doesn't work in a lambda, so you simply get a compile error instead.
Or let the compiler infer the types. Try this:
let f2 x =
fun s ->
match x with
| x when x > 0 -> printfn "%s" s
| _ -> printfn "%s" "Please give me a number that is greater than 0"

How to get culture-aware output with printf-like functions?

Is there a way to use F#'s sprintf float formating with a decimal comma? It would be nice if this worked:
sprintf "%,1f" 23.456
// expected: "23,456"
Or can I only use String.Format Method (IFormatProvider, String, Object()) ?
EDIT: I would like to have a comma not a point as a decimal separator. Like most non-English speaking countries use it.
It's quite a pain, but you can write your own version of sprintf that does exactly what you want:
open System
open System.Text.RegularExpressions
open System.Linq.Expressions
let printfRegex = Regex(#"^(?<text>[^%]*)((?<placeholder>%(%|((0|-|\+| )?([0-9]+)?(\.[0-9]+)?b|c|s|d|i|u|x|X|o|e|E|f|F|g|G|M|O|A|\+A|a|t)))(?<text>[^%]*))*$", RegexOptions.ExplicitCapture ||| RegexOptions.Compiled)
type PrintfExpr =
| K of Expression
| F of ParameterExpression * Expression
let sprintf' (c:System.Globalization.CultureInfo) (f:Printf.StringFormat<'a>) : 'a =
//'a has form 't1 -> 't2 -> ... -> string
let cultureExpr = Expression.Constant(c) :> Expression
let m = printfRegex.Match(f.Value)
let prefix = m.Groups.["text"].Captures.[0].Value
let inputTypes =
let rec loop t =
if Reflection.FSharpType.IsFunction t then
let dom, rng = Reflection.FSharpType.GetFunctionElements t
dom :: loop rng
else
if t <> typeof<string> then
failwithf "Unexpected return type: %A" t
[]
ref(loop typeof<'a>)
let pop() =
let (t::ts) = !inputTypes
inputTypes := ts
t
let exprs =
K(Expression.Constant(prefix)) ::
[for i in 0 .. m.Groups.["placeholder"].Captures.Count - 1 do
let ph = m.Groups.["placeholder"].Captures.[i].Value
let text = m.Groups.["text"].Captures.[i+1].Value
// TODO: handle flags, width, precision, other placeholder types, etc.
if ph = "%%" then yield K(Expression.Constant("%" + text))
else
match ph with
| "%f" ->
let t = pop()
if t <> typeof<float> && t <> typeof<float32> then
failwithf "Unexpected type for %%f placeholder: %A" t
let e = Expression.Variable t
yield F(e, Expression.Call(e, t.GetMethod("ToString", [| typeof<System.Globalization.CultureInfo> |]), [cultureExpr]))
| "%s" ->
let t = pop()
if t <> typeof<string> then
failwithf "Unexpected type for %%s placeholder: %A" t
let e = Expression.Variable t
yield F(e, e)
| _ ->
failwithf "unhandled placeholder: %s" ph
yield K (Expression.Constant text)]
let innerExpr =
Expression.Call(typeof<string>.GetMethod("Concat", [|typeof<string[]>|]), Expression.NewArrayInit(typeof<string>, exprs |> Seq.map (fun (K e | F(_,e)) -> e)))
:> Expression
let funcConvert =
typeof<FuncConvert>.GetMethods()
|> Seq.find (fun mi -> mi.Name = "ToFSharpFunc" && mi.GetParameters().[0].ParameterType.GetGenericTypeDefinition() = typedefof<Converter<_,_>>)
let body =
List.foldBack (fun pe (e:Expression) ->
match pe with
| K _ -> e
| F(p,_) ->
let m = funcConvert.MakeGenericMethod(p.Type, e.Type)
Expression.Call(m, Expression.Lambda(m.GetParameters().[0].ParameterType, e, p))
:> Expression) exprs innerExpr
Expression.Lambda(body, [||]).Compile().DynamicInvoke() :?> 'a
sprintf' (Globalization.CultureInfo.GetCultureInfo "fr-FR") "%s %f > %f" "It worked!" 1.5f -12.3
Taking a look at source code of Printf module, it uses invariantCulture. I don't think printf-like functions are culture aware.
If you always need a comma, you could use sprintf and string.Replace function. If your code is culture-dependent, using ToString or String.Format is your best bet.

F# Quotations - traversing into function calls represented by a Value

I've spent a few hours trying to get to grips with F# Quotations, but I've come across a bit of a road block. My requirement is to take simple functions (just integers,+,-,/,*) out of a discriminated union type and generate an expression tree that will eventually be used to generate C code. I know this is possible using Quotations with 'direct' functions.
My problem is that the expression tree seems to terminate with a "Value", and I can't figure out how to traverse into that value.
My questions is
whether this is actually possible in this situation? or are there any other approaches that are worth considering.
type FuncType =
| A of (int -> int -> int)
| B
| C
[<ReflectedDefinition>]
let add x y = x + y
let myFunc1 = A (fun x y -> x + y )
let myFunc2 = A add
let thefunc expr =
match expr with
| A(x) ->
<# x #>
| _ ->
failwith "fail"
printfn "%A" (thefunc myFunc1) // prints "Value (<fun:myFunc1#14>)"
printfn "%A" (thefunc myFunc2) // prints "Value (<fun:myFunc2#15>)"
printfn "%A" <# fun x y -> x + y #> // generates usable expression tree
Quotations represent the F# code that was quoted syntactically. This means that if you write something like <# x #>, the quotation will contain just Value case specifying that you quoted something which has the specified value. (Variables are automatically replaced with values if the variable is defined outside of the quotation).
You can only get quotation of code that was explicitly quoted using <# .. #> or of a function that was marked as ReflectedDefinition and is referred to by name in a quotation (e.g. <# add #> but not for example let f = add in <# f #>).
To be able to do what your snippet suggests, you'll need to store quotations in your FuncType too (so that the lambda function that you write is also quoted and you can get its body). Something like:
type FuncType =
| A of Expr<int -> int -> int>
| B | C
[<ReflectedDefinition>]
let add x y = x + y
let myFunc1 = A <# fun x y -> x + y #>
let myFunc2 = A <# add #>
let thefunc expr =
match expr with
| A(x) -> x
| _ -> failwith "fail"
This should work for functions marked as ReflectedDefinition too. To extract the body of the function you need to add something like (you'll need to substitute arguments of the function for parameters, but this should give you some idea):
match expr with
| Lambdas(_, body) ->
match body with
| Call(_, mi, _) when Expr.TryGetReflectedDefinition(mi) <> None ->
let func = Expr.TryGetReflectedDefinition(mi)
match func with
| Some(Lambdas(_, body)) ->
// 'body' is the quotation of the body
| _ -> failwith "Not supported function"
| _ -> failwith "Not supported function"
| _ -> failwith "Not supported expression"

Resources