Simple closure function - f#

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"

Related

What is the leading ? is F# type signature?

When I hover certain methods that come from C# libraries in F#, some of the parameters start with a ?. I'm unfamiliar with this syntax. Does this mean nullable?
Here is an example from hovering the SetStatus method on the Activity class where the description parameter is preceded by a ?.
The optional parameters in F# are declared with question marks in the declaration of the function:
https://learn.microsoft.com/en-us/dotnet/fsharp/language-reference/parameters-and-arguments#optional-parameters
What is interesting that the optionality expressed this way turns them to actual options of the base type, however there are differences: The options are 'active' only within the scope of the member method, and you have to pass the underlying type variable (or nothing in this case)
type Test() =
member this.fn (?i : int) =
match i with
| Some x -> -x
| None -> 0
let t = new Test()
let r1 = t.fn()
printfn "%d" r1
let r2 = t.fn(4)
printfn "%d" r2
If you declare your member method as int option, you can't omit the parameter despite identical implementation of the method otherwise:
type Test() =
member this.fn (i : int option) =
match i with
| Some x -> -x
| None -> 0
let t = new Test()
let r1 = t.fn()
printfn "%d" r1
let r2 = t.fn(4)
printfn "%d" r2
Here's the output:
/home/jdoodle.fs(9,14): error FS0001: This expression was expected to have type
'int option'
but here has type
'unit'
/home/jdoodle.fs(12,15): error FS0001: This expression was expected to have type
'int option'
but here has type
'int'
In order to make it working, you have to pass int option to the method:
let r1 = t.fn(None)
printfn "%d" r1
let r2 = t.fn(Some 4)
printfn "%d" r

How to print function argument name that was used to call this function in F#

How can I print argument function name that was used to call this function?
open System
open System.Threading.Tasks
let logger (f: ('a -> Task<'b>)) : ('a -> Task<'b>) =
printfn "Hey: %O" (nameof f) // I would like to print "myFunc", not "f"
f
let myFunc x = task {return x }
let d = (logger myFunc) 3
You could use the ReflectedDefinition(true) attribute, which automatically quotes the argument of a method call and gives you both the value (to use at runtime) and the code quotation from which you can (if the format is right) extract the name. This only seems to work with method calls though:
type Logger =
static member log([<ReflectedDefinition(true)>]f: Expr<('a -> Task<'b>)>) : ('a -> Task<'b>) =
match f with
| Patterns.WithValue(v, _, Patterns.Lambda(_, Patterns.Call(_, mi, _))) ->
printfn "Hello %s!" mi.Name
unbox v
| _ -> failwith "Wrong format"
let myFunc x = task {return x }
let d = (Logger.log myFunc) 3
The design and motivation of this is discussed in the F# 4.0 Speclet: Auto-Quotation of Arguments at Method Calls

Can I make return type vary with parameter a bit like sprintf in F#?

In the F# core libraries there are functions whose signature seemingly changes based on the parameter at compile-time:
> sprintf "Hello %i" ;;
val it : (int -> string) = <fun:it#1>
> sprintf "Hello %s" ;;
val it : (string -> string) = <fun:it#2-1>
Is it possible to implement my own functions that have this property?
For example, could I design a function that matches strings with variable components:
matchPath "/products/:string/:string" (fun (category : string) (sku : string) -> ())
matchPath "/tickets/:int" (fun (id : int) -> ())
Ideally, I would like to do avoid dynamic casts.
There are two relevant F# features that make it possible to do something like this.
Printf format strings. The compiler handles format strings like "hi %s" in a special way. They are not limited just to printf and it's possible to use those in your library in a somewhat different way. This does not let you change the syntax, but if you were happy to specify your paths using e.g. "/products/%s/%d", then you could use this. The Giraffe library defines routef function, which uses this trick for request routing:
let webApp =
choose [
routef "/foo/%s/%s/%i" fooHandler
routef "/bar/%O" (fun guid -> text (guid.ToString()))
]
Type providers. Another option is to use F# type providers. With parameterized type providers, you can write a type that is parameterized by a literal string and has members with types that are generated by some F# code you write based on the literal string parameter. An example is the Regex type provider:
type TempRegex = Regex< #"^(?<Temperature>[\d\.]+)\s*°C$", noMethodPrefix = true >
TempRegex().Match("21.3°C").Temperature.TryValue
Here, the regular expression on the first line is static parameter of the Regex type provider. The type provider generates a Match method which returns an object with properties like Temperature that are based on the literal string. You would likely be able to use this and write something like:
MatchPath<"/products/:category/:sku">.Match(fun r ->
printfn "Got category %s and sku %s" r.Category r.Sku)
I tweaked your example so that r is an object with properties that have names matching to those in the string, but you could use a lambda with multiple parameters too. Although, if you wanted to specify types of those matches, you might need a fancier syntax like "/product/[category:int]/[sku:string]" - this is just a string you have to parse in the type provider, so it's completely up to you.
1st: Tomas's answer is the right answer.
But ... I had the same question.
And while I could understand it conceptually as "it has to be 'the string format thing' or 'the provider stuff'"
I could not tell my self that I got until I tried an implementation
... And it took me a bit .
I used FSharp.Core's printfs and Giraffe's FormatExpressions.fs as guidelines
And came up with this naive gist/implementation, inspired by Giraffe FormatExpressions.fs
BTW The trick is in this bit of magic fun (format: PrintfFormat<_, _, _, _, 'T>) (handle: 'T -> 'R)
open System.Text.RegularExpressions
// convert format pattern to Regex Pattern
let rec toRegexPattern =
function
| '%' :: c :: tail ->
match c with
| 'i' ->
let x, rest = toRegexPattern tail
"(\d+)" + x, rest
| 's' ->
let x, rest = toRegexPattern tail
"(\w+)" + x, rest
| x ->
failwithf "'%%%c' is Not Implemented\n" x
| c :: tail ->
let x, rest = toRegexPattern tail
let r = c.ToString() |> Regex.Escape
r + x, rest
| [] -> "", []
// Handler Factory
let inline Handler (format: PrintfFormat<_, _, _, _, 'T>) (handle: 'T -> string) (decode: string list -> 'T) =
format.Value.ToCharArray()
|> List.ofArray
|> toRegexPattern
|> fst, handle, decode
// Active Patterns
let (|RegexMatch|_|) pattern input =
let m = Regex.Match(input, pattern)
if m.Success then
let values =
[ for g in Regex(pattern).Match(input).Groups do
if g.Success && g.Name <> "0" then yield g.Value ]
Some values
else
None
let getPattern (pattern, _, _) = pattern
let gethandler (_, handle, _) = handle
let getDecoder (_, _, decode) = decode
let Router path =
let route1 =
Handler "/xyz/%s/%i"
(fun (category, id) ->
// process request
sprintf "handled: route1: %s/%i" category id)
(fun values ->
// convert matches
values |> List.item 0,
values
|> List.item 1
|> int32)
let route2 =
Handler "/xyz/%i"
(fun (id) -> sprintf "handled: route2: id: %i" id) // handle
(fun values -> values|> List.head |> int32) // decode
// Router
(match path with
| RegexMatch (getPattern route2) values ->
values
|> getDecoder route2
|> gethandler route2
| RegexMatch (getPattern route1) values ->
values
|> getDecoder route1
|> gethandler route1
| _ -> failwith "No Match")
|> printf "routed: %A\n"
let main argv =
try
let arg = argv |> Array.skip 1 |> Array.head
Router arg
0 // return an integer exit code
with
| Failure msg ->
eprintf "Error: %s\n" msg
-1

Choice type in 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)

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