Simple recursive function f# - f#

This is an example from my professors book, but when I try to run it in f# it doesn't work. Can someone point out what is wrong here?
let rec readNonZeroValue a =
let a = int (System.Console. ReadLine ())
match a with
|0 ->
printfn "Error: zero value entered. Try again"
readNonZeroValue ()
|_ ->
a
printfn "Please enter a non-zero value"
let b = readNonZeroValue ()
printfn "You typed: %A" b
I am beginner, so sorry for asking such a simple question.
The point of the code is simply for the user to be able to type in a number and then get it printed to the terminal, for any other number than 0.
I have another very similar piece of code that actually works, only difference is that it takes a string instead:
let rec progLang a =
printfn "Please enter the name of a programming language"
let a = string (System.Console.ReadLine())
match a with
|"Fsharp" ->
printfn "%A is cool" a
progLang ()
|"quit" -> a
|_ ->
printfn "I don't know %A" a
progLang ()

Lets start with the function that works.
let rec progLang a =
printfn "Please enter the name of a programming language"
let a = string (System.Console.ReadLine())
match a with
|"Fsharp" ->
printfn "%A is cool" a
progLang ()
|"quit" -> a
|_ ->
printfn "I don't know %A" a
progLang ()
"let rec progLang a" is a bit odd because the variable is inferred to be of type Unit, so the code may as well say
let rec progLang () =
printfn "Please enter the name of a programming language"
... etc ...
So for the one that doesnt work, you need to ensure the indentation is correct, AND I think the code u have pasted is of a function, plus some code that calls the function, the function should be this (if you're learning it may be an idea to put the type of the function in a comment - I do this quite a lot).
// Unit -> int
let rec readNonZeroValue a =
let a = int (System.Console. ReadLine ())
match a with
|0 ->
printfn "Error: zero value entered. Try again"
readNonZeroValue ()
|_ ->
a
So its a function that takes unit and returns an int, and you could potentially call it with code like this:
// unit -> unit
let codeThatCalls () =
printfn "Please enter a non-zero value"
let b = readNonZeroValue ()
printfn "You typed: %A" b
The moral of the story is IDENTATION is important, and can completely change the meaning of your code.

Related

type mismatch error for async chained operations

Previously had a very compact and comprehensive answer for my question.
I had it working for my custom type but now due to some reason I had to change it to string type which is now causing type mismatch errors.
module AsyncResult =
let bind (binder : 'a -> Async<Result<'b, 'c>>) (asyncFun : Async<Result<'a, 'c>>) : Async<Result<'b, 'c>> =
async {
let! result = asyncFun
match result with
| Error e -> return Error e
| Ok x -> return! binder x
}
let compose (f : 'a -> Async<Result<'b, 'e>>) (g : 'b -> Async<Result<'c, 'e>>) = fun x -> bind g (f x)
let (>>=) a f = bind f a
let (>=>) f g = compose f g
Railway Oriented functions
let create (json: string) : Async<Result<string, Error>> =
let url = "http://api.example.com"
let request = WebRequest.CreateHttp(Uri url)
request.Method <- "GET"
async {
try
// http call
return Ok "result"
with :? WebException as e ->
return Error {Code = 500; Message = "Internal Server Error"}
}
test
type mismatch error for the AsyncResult.bind line
let chain = create
>> AsyncResult.bind (fun (result: string) -> (async {return Ok "more results"}))
match chain "initial data" |> Async.RunSynchronously with
| Ok data -> Assert.IsTrue(true)
| Error error -> Assert.IsTrue(false)
Error details:
EntityTests.fs(101, 25): [FS0001] Type mismatch. Expecting a '(string -> string -> Async<Result<string,Error>>) -> 'a' but given a 'Async<Result<'b,'c>> -> Async<Result<'d,'c>>' The type 'string -> string -> Async<Result<string,Error>>' does not match the type 'Async<Result<'a,'b>>'.
EntityTests.fs(101, 25): [FS0001] Type mismatch. Expecting a '(string -> string -> Async<Result<string,Error>>) -> 'a' but given a 'Async<Result<string,'b>> -> Async<Result<string,'b>>' The type 'string -> string -> Async<Result<string,Error>>' does not match the type 'Async<Result<string,'a>>'.
Edit
Curried or partial application
In context of above example, is it the problem with curried functions? for instance if create function has this signature.
let create (token: string) (json: string) : Async<Result<string, Error>> =
and then later build chain with curried function
let chain = create "token" >> AsyncResult.bind (fun (result: string) -> (async {return Ok "more results"}))
Edit 2
Is there a problem with following case?
signature
let create (token: Token) (entityName: string) (entityType: string) (publicationId: string) : Async<Result<string, Error>> =
test
let chain = create token >> AsyncResult.bind ( fun (result: string) -> async {return Ok "more results"} )
match chain "test" "article" "pubid" |> Async.RunSynchronously with
Update: At the front of the answer, even, since your edit 2 changes everything.
In your edit 2, you have finally revealed your actual code, and your problem is very simple: you're misunderstanding how the types work in a curried F# function.
When your create function looked like let create (json: string) = ..., it was a function of one parameter. It took a string, and returned a result type (in this case, Async<Result<string, Error>>). So the function signature was string -> Async<Result<string, Error>>.
But the create function you've just shown us is a different type entirely. It takes four parameters (one Token and three strings), not one. That means its signature is:
Token -> string -> string -> string -> Async<Result<string, Error>>
Remember how currying works: any function of multiple parameters can be thought of as a series of functions of one parameter, which return the "next" function in that chain. E.g., let add3 a b c = a + b + c is of type int -> int -> int -> int; this means that add3 1 returns a function that's equivalent to let add2 b c = 1 + b + c. And so on.
Now, keeping currying in mind, look at your function type. When you pass a single Token value to it as you do in your example (where it's called as create token, you get a function of type:
string -> string -> string -> Async<Result<string, Error>>
This is a function that takes a string, which returns another function that takes a string, which returns a third function which takes a string and returns an Async<Result<whatever>>. Now compare that to the type of the binder parameter in your bind function:
(binder : 'a -> Async<Result<'b, 'c>>)
Here, 'a is string, so is 'b, and 'c is Error. So when the generic bind function is applied to your specific case, it's looking for a function of type string -> Async<Result<'b, 'c>>. But you're giving it a function of type string -> string -> string -> Async<Result<string, Error>>. Those two function types are not the same!
That's the fundamental cause of your type error. You're trying to apply a function that returns a function that returns function that returns a result of type X to a design pattern (the bind design pattern) that expects a function that returns a result of type X. What you need is the design pattern called apply. I have to leave quite soon so I don't have time to write you an explanation of how to use apply, but fortunately Scott Wlaschin has already written a good one. It covers a lot, not just "apply", but you'll find the details about apply in there as well. And that's the cause of your problem: you used bind when you needed to use apply.
Original answer follows:
I don't yet know for a fact what's causing your problem, but I have a suspicion. But first, I want to comment that the parameter names for your AsyncResult.bind are wrong. Here's what you wrote:
let bind (binder : 'a -> Async<Result<'b, 'c>>)
(asyncFun : Async<Result<'a, 'c>>) : Async<Result<'b, 'c>> =
(I moved the second parameter in line with the first parameter so it wouldn't scroll on Stack Overflow's smallish column size, but that would compile correctly if the types were right: since the two parameters are lined up vertically, F# would know that they are both belonging to the same "parent", in this case a function.)
Look at your second parameter. You've named it asyncFun, but there's no arrow in its type description. That's not a function, it's a value. A function would look like something -> somethingElse. You should name it something like asyncValue, not asyncFun. By naming it asyncFun, you're setting yourself up for confusion later.
Now for the answer to the question you asked. I think your problem is this line, where you've fallen afoul of the F# "offside rule":
let chain = create
>> AsyncResult.bind (fun (result: string) -> (async {return Ok "more results"}))
Note the position of the >> operator, which is to the left of its first operand. Yes, the F# syntax appears to allow that in most situations, but I suspect that if you simply change that function definition to the following, your code will work:
let chain =
create
>> AsyncResult.bind (fun (result: string) -> (async {return Ok "more results"}))
Or, better yet because it's good style to make the |> (and >>) operators line up with their first operand:
let chain =
create
>> AsyncResult.bind (fun (result: string) -> (async {return Ok "more results"}))
If you look carefully at the rules that Scott Wlaschin lays out in https://fsharpforfunandprofit.com/posts/fsharp-syntax/, you'll note that his examples where he shows exceptions to the "offside rule", he writes them like this:
let f g h = g // defines a new line at col 15
>> h // ">>" allowed to be outside the line
Note how the >> character is still to the right of the = in the function definition. I don't know exactly what the F# spec says about the combination of function definitions and the offside rule (Scott Wlaschin is great, but he's not the spec so he could be wrong, and I don't have time to look up the spec right now), but I've seen it do funny things that I didn't quite expect when I wrote functions with part of the function definition on the same line as the function, and the rest on the next line.
E.g., I once wrote something like this, which didn't work:
let f a = if a = 0 then
printfn "Zero"
else
printfn "Non-zero"
But then I changed it to this, which did work:
let f a =
if a = 0 then
printfn "Zero"
else
printfn "Non-zero"
I notice that in Snapshot's answer, he made your chain function be defined on a single line, and that worked for him. So I suspect that that's your problem.
Rule of thumb: If your function has anything after the = on the same line, make the function all on one line. If your function is going to be two lines, put nothing after the =. E.g.:
let f a b = a + b // This is fine
let g c d =
c * d // This is also fine
let h x y = x
+ y // This is asking for trouble
I would suspect that the error stems from a minor change in indentation since adding a single space to an FSharp program changes its meaning, the FSharp compiler than quickly reports phantom errors because it interprets the input differently. I just pasted it in and added bogus classes and removed some spaces and now it is working just fine.
module AsyncResult =
[<StructuralEquality; StructuralComparison>]
type Result<'T,'TError> =
| Ok of ResultValue:'T
| Error of ErrorValue:'TError
let bind (binder : 'a -> Async<Result<'b, 'c>>) (asyncFun : Async<Result<'a, 'c>>) : Async<Result<'b, 'c>> =
async {
let! result = asyncFun
match result with
| Error e -> return Error e
| Ok x -> return! binder x
}
let compose (f : 'a -> Async<Result<'b, 'e>>) (g : 'b -> Async<Result<'c, 'e>>) = fun x -> bind g (f x)
let (>>=) a f = bind f a
let (>=>) f g = compose f g
open AsyncResult
open System.Net
type Assert =
static member IsTrue (conditional:bool) = System.Diagnostics.Debug.Assert(conditional)
type Error = {Code:int; Message:string}
[<EntryPoint>]
let main args =
let create (json: string) : Async<Result<string, Error>> =
let url = "http://api.example.com"
let request = WebRequest.CreateHttp(Uri url)
request.Method <- "GET"
async {
try
// http call
return Ok "result"
with :? WebException as e ->
return Error {Code = 500; Message = "Internal Server Error"}
}
let chain = create >> AsyncResult.bind (fun (result: string) -> (async {return Ok "more results"}))
match chain "initial data" |> Async.RunSynchronously with
| Ok data -> Assert.IsTrue(true)
| Error error -> Assert.IsTrue(false)
0

"let is unfinished. expect an expression" error. I don't see where though

open System
let highLowGame () =
let rng = new Random();
let secretNumber = rng.Next() % 100 + 1
let rec highLowGameStep () =
printfn "Guess a number: "
let guessStr = Console.ReadLine()
let guess = Int32.Parse(guessStr)
match guess with
| _ when guess > secretNumber -> printfn "Too high!" highLowGameStep ()
| _ when guess = secretNumber -> printfn "You got it!" ()
| _ when guess < secretNumber -> printfn "Too low!" highLowGameStep ()
[<EntryPoint>]
let main argv =
highLowGame ()
0 // return an integer exit code
I know there's tons of these questions and I get that a function in F# must have a return variable. Mine is here | _ when guess = secretNumber -> printfn "You got it!" () so I don't understand why it keeps telling me that my block is unfinished
This example is straight out of the F# 3.0 book.
/stdin(14,13): error FS0010: Unexpected identifier in expression. Expected incomplete structured construct at or before this point or other token.
is the full error.
You have to return something at the end of your let statement. Otherwise, your function just defines some values, but the expression isn't complete - you're missing a return value. See this MSDN link for more details.
In this case, you can add highLowGameStep () at the end to call the function and get its return value:
open System
let highLowGame () =
let rng = new Random();
let secretNumber = rng.Next() % 100 + 1
let rec highLowGameStep () =
printfn "Guess a number: "
let guessStr = Console.ReadLine()
let guess = Int32.Parse(guessStr)
match guess with
| _ when guess > secretNumber -> printfn "Too high!" highLowGameStep ()
| _ when guess = secretNumber -> printfn "You got it!" ()
| _ when guess < secretNumber -> printfn "Too low!" highLowGameStep ()
highLowGameStep ()
[<EntryPoint>]
let main argv =
highLowGame ()
0 // return an integer exit code
I was getting the same error as OP for a different reason. The reason was improper indentation. Here is my code:
open System
type Temperature = F of int | C of int
[<EntryPoint>]
let main (argv : string[]) =
let freezing = F 32;
Console.WriteLine("A union: {0}", freezing ); //problematic indentation
printfn "A union: %A" freezing ; //problematic indentation
0
I had copy pasted two lines of code (marked as problematic indentation in comments) from a website and it went haywire. It was giving me three different compile time errors at three different lines of code within main function. When I aligned the indentation of all four statements within main function the issue got resolved:
let main (argv : string[]) =
let freezing = F 32;
Console.WriteLine("A union: {0}", freezing );
printfn "A union: %A" freezing ;
0
I would encourage you to enable View White Space option in Visual Studio IDE while working on F# as mentioned here. Tabs, spaces and code indentation is strongly connected to scoping in F#. Read these posts to gather more understanding around scoping and indentation in F#:
Whitespace and indentation in F#
#indent "off" in F#
Roujo has an excellent answer to your question, I'm throwing up another answer to go more in depth into the fundamentals of what's going on.
The key to remember is that everything in F# must be an expression and an expression is something which has a value. That value could be an integer or a float or a function, but it's gotta have a value. The let isn't, on it's own, an expression; it's a binding of a value to a name so that name can be used in an expression. In your code, you've bound the name highLowGameStep to a function value, but you don't use that name in an expression. The F# compiler is basically left holding the bag, wondering what expression highLowGameStep should be used in.
It helps to use the verbose F# syntax to see what's happening. In verbose F# the code for your function is (note the in keyword after each let binding):
let rng = new Random() in
let secretNumber = rng.Next() % 100 + 1 in
let rec highLowGameStep () =
printfn "Guess a number: "
let guessStr = Console.ReadLine()
let guess = Int32.Parse(guessStr)
match guess with
| _ when guess > secretNumber ->
printfn "Too high!"
highLowGameStep ()
| _ when guess = secretNumber ->
printfn "You got it!"
| _ when guess < secretNumber ->
printfn "Too low!"
highLowGameStep ()
in
In this syntax, it's obvious what's wrong: there's nothing after the last in where F# expects an expression. (Incidentally, the code in the match statements wouldn't have executed because there needed to be a line or ; separating the printfn function call and the call to highLowGameStep.)
Quick summary, the let is binding a name to a value to be used in an expression. In the code example, there was no expression for the bound name to be used in and the compiler failed.

How to pattern match on the type of the message received in F# akka.net?

Please see last edit.
Apologies for the newbie question. I am trying to implement something in F# using Akka.net. I'm very new to F# and I have only used Akka from Scala. Basically I am trying to implement something that's pretty easy in Scala, namely making an Actor do different things based on the type of message it receives.
My code is below and it's a slight modification of the hello world example lifted from the akka.net website. I believe a first problem with my code is that it does record pattern matching instead of type pattern matching, however I was unable to write a type match one without compilation errors... Any help will be greatly appreciated. Thank you.
open Akka.FSharp
open Actors
open Akka
open Akka.Actor
type Entries = { Entries: List<string>}
let system = ActorSystem.Create "MySystem"
let feedBrowser = spawn system "feedBrowser" <| fun mailbox ->
let rec loop() = actor {
let! msg = mailbox.Receive()
match msg with
| { Entries = entries} -> printf "%A" entries
| _ -> printf "unmatched message %A" msg
return! loop()}
loop()
[<EntryPoint>]
let main argv =
feedBrowser <! "abc" // this should not blow up but it does
system.AwaitTermination()
0
Edit: the error is a runtime one, System.InvalidCastException, unable to cast object of type String to Entries.
Later edit: I got this to work with this change, downcasting to Object:
let feedBrowser = spawn system "feedBrowser" <| fun mailbox ->
let rec loop() = actor {
let! msg = mailbox.Receive()
let msgObj = msg :> Object
match msgObj with
| :? Entries as e -> printfn "matched message %A" e
| _ -> printf "unmatched message %A" msg
return! loop()}
loop()
Now these two lines work correctly
feedBrowser <! "abc"
feedBrowser <! { Entries = ["a"; "b"] }
the first one prints "unmatched message abc" and the second outputs the entries.
Is there a better way of going about this, without the cast? Does akka.net have something specifically for this case?
Thank you.
You should use a Discriminated Union (the Command type in this example). Then you can pattern match its options.
type Entries = { Entries: List<string>}
type Command =
| ListEntries of Entries
| OtherCommand of string
let stack() =
let system = ActorSystem.Create "MySystem"
let feedBrowser = spawn system "feedBrowser" <| fun mailbox ->
let rec loop() = actor {
let! msg = mailbox.Receive()
match msg with
| ListEntries { Entries = entries} -> printf "%A" entries
| OtherCommand s -> printf "%s" s
return! loop() }
loop()
And to send the message you should use:
feedBrowser <! OtherCommand "abc"
feedBrowser <! ListEntries { Entries = ["a"; "b"] }
It's important to say that the send operator has the following signature:
#ICanTell -> obj -> unit
So, if you pass an message with a different type, like a string, it'll raise an exception.

How to manage debug printing in F#

I want to add debug printing to my project with a function having a type signature something like:
bool -> Printf.TextWriterFormat<'a> -> 'a
i.e. it should take a bool indicating whether or not we are in verbose mode, and use that to take the decision about whether to print or not.
For example, lets say dprint : bool -> Printf.TextWriterFormat<'a> -> 'a then I would like this behaviour:
> dprint true "Hello I'm %d" 52;;
Hello I'm 52
val it : unit = ()
> dprint false "Hello I'm %d" 52;;
val it : unit = ()
The idea is that a command line flag can be used to avoid control this output. I also want to avoid a runtime cost in the "not verbose" case. It is possible to define a function that works like this using kprintf:
let dprint (v: bool) (fmt: Printf.StringFormat<'a,unit>) =
let printVerbose (s: string) =
if v then System.Console.WriteLine(s)
fmt |> Printf.kprintf printVerbose
but printing/ignoring a sequence of numbers with List.iter (dprint b "%A") [1..10000] (b \in {true,false}) takes amount 1.5s for both values of b on my machine.
I came up with another method using reflection that builds an appropriately typed function to discard the formatting arguments:
let dprint (v: bool) (fmt: Printf.TextWriterFormat<'a>) : 'a =
let rec mkKn (ty: System.Type) =
if FSharpType.IsFunction(ty) then
let _, ran = FSharpType.GetFunctionElements(ty)
FSharpValue.MakeFunction(ty,(fun _ -> mkKn ran))
else
box ()
if v then
printfn fmt
else
unbox<'a> (mkKn typeof<'a>)
but here the reflection seems too expensive (even more so than that done inside the standard libraries complicated definition of printf sometimes).
I don't want to litter my code with things like:
if !Options.verbose then
printfn "Debug important value: %A" bigObject5
or closures:
dprint (fun () -> printfn "Debug important value: %A" bigObject5)
so, are there any other solutions?
I like your solution using reflection. How about caching it on the type level so that you pay the price of reflection only once per type? For example:
let rec mkKn (ty: System.Type) =
if Reflection.FSharpType.IsFunction(ty) then
let _, ran = Reflection.FSharpType.GetFunctionElements(ty)
// NOTICE: do not delay `mkKn` invocation until runtime
let f = mkKn ran
Reflection.FSharpValue.MakeFunction(ty, fun _ -> f)
else
box ()
[<Sealed>]
type Format<'T> private () =
static let instance : 'T =
unbox (mkKn typeof<'T>)
static member Instance = instance
let inline dprint verbose args =
if verbose then
printfn args
else
Format<_>.Instance
A pragmatist would just use the fast C# formatted printing machinery instead of this. I avoid Printf functions in production code because of the overhead they have, as you point out. But then F# printing definitely feels nicer to use.
My #time results for List.iter (dprint false "%A") [1..10000]:
Original version : 0.85
Original version with reflection : 0.27
The proposed version : 0.03
How about this:
/// Prints a formatted string to DebugListeners.
let inline dprintfn fmt =
Printf.ksprintf System.Diagnostics.Debug.WriteLine fmt
Then you can write:
dprintfn "%s %s" "Hello" "World!"
Debug.WriteLine(...) is marked with [<Conditional("DEBUG")>] so the F# compiler should be able to eliminate the entire statement at compile-time (though you'll have to experiment and check the compiled IL to see if it actually does.
Note that this solution only works if you don't care about changing the verbosity at run-time. If that's the case, you'll have to look for a different solution.
UPDATE : Out of curiousity, I just tried this code (it does work) and the F# 2.0 compiler doesn't compile everything away (even with optimizations on), so the speed is the same whether debugging or not. There might be other ways to get the compiler to eliminate the whole statement to fix the speed issue, but you'll just have to experiment a bit to find out.
Why not use #defines just do
let dprint (fmt: Printf.StringFormat<'a,unit>) =
#if DEBUG
let printVerbose (s: string) =
System.Console.WriteLine(s)
fmt |> Printf.kprintf printVerbose
#else
fun _ -> ()
On my machine the sample test takes 0.002s in the optimised version

Printfn value is not a function and cannot be applied in F#'s interactive window

This is probably something simple, but I have a .fs file with a simple sample function.
let printHello = printfn "%A" "Hello"
I have set the search path to the .fs file using
>#I "PathToMyFSFile"
I have loaded my file using
>#load "Test.fs"
Which worked fine. Now I want to call the function which actually prints the hello to screen, but thats turning out to be too difficult
> Test.printHello;;
val it : unit = ()
Tried Test.printHello();; as well but doesn't work. How do I actually make it print "Hello" to screen?
your current printHello isn't actually a function. To make it a function you need to do
let printHello() = printfn "%A" "Hello"
noice the (). Then everything should work.
EDIT:
When the compiler sees your definition
let printHello = printfn "%A" "Hello"
it passes it as a simple data term. For example, consider this program:
let printHello = printfn "%A" "Hello"
printfn "World"
printHello
This will print "Hello" then "World". printHello just has unit type, so does nothing. Compare it to
let printHello() = printfn "%A" "Hello"
printfn "World"
printHello()
Here printHello is a function. In this case, the function is only executed when it is explicitly called, so this prints "World" then "Hello".
As John already said, your printHello isn't a function - it is a value of type unit. When you give printfn all the required arguments (as you did), it does the imperative operation and return unit (which is a type with only a single value written as ()). You can see that writing that declaration does the printing immediately:
> let printHello = printfn "%A" "Hello";;
"Hello"
val printHello : unit = ()
When you use printHello later, it simply refers to this unit value (which does not carry any information).
If you want to make it a function (of type unit -> unit) that will do something each time it is executed, then you can use the sample that John posted.
The function printfn was not partially applied, because you gave it all the parameters it required (so it could just print immediately). If you wanted to use partial application, you could use something like:
> let printHello = printfn "%s %s" "Hello";; // Note - didn't give value for second %s
val printHello : string -> unit
Now printHello is a function that waits for the second parameter and then runs:
> printHello "World";;
Hello World
val it : unit = ()
> printHello "F#";;
Hello F#
val it : unit = ()
As has already been said in other answers, "printHello" set to () is unit, the return value of printfn is () , console print is side-effect.
use Lazy:
let printHello = Lazy (fun () ->printfn "%A" "Hello")
DEMO
> Test.printHello.Value;;
"Hello"
val it : unit = ()
> Test.printHello.Value;;
val it : unit = () //only once
use Seq:
let printHello = seq { printfn "%A" "Hello"; yield ()}
DEMO
> Test.printHello;;
"Hello"
val it : seq<unit> = seq [null]
> Test.printHello;;
"Hello"
val it : seq<unit> = seq [null] //many times

Resources