I'm beginner in F#, What does %-5s and %5s do in the following code? I thought it gives space paddings but I'm not sure how it pads?
printfn "%-5s %5s" "a" "b"
When I tried printf "%-5s %5s" "a" "b" "v"
or printf "%-5s %-5s" "a" "b" "c"
That gives me an type match error, I don't understand the syntax, It dosen't seem that it is printing the concatenation of the three strings "%-5s %5s", "a" and "b". It seems to put "a" and "b" between the %5s. so why can't I add "c" after? Also, I'm following tutorial on Youtube: https://www.youtube.com/watch?v=c7eNDJN758U
If There is any other good source of learning the essence of functional language by F#, please give some suggesting!
The %5s and %-5s are formatting codes along with width and alignments specified.
The hyphen in your first code aligns the value to the left.
As an example, I have the following 2 lines:
printfn "%-5s %5s" "a" "b"
printfn "%-5s %5s" "yo" "hey!"
What gets printed is the following:
a b
yo hey!
Here is a page that explains more about the printfn function. The entire site is an excellent resource for learning to use F#.
Good luck!
PS - as for your question about the error when adding the 3rd parameter, the printfn function will check for both the types and number of parameters you supply based on the format codes in the string. This is explained in the linked page I included earlier.
Related
I'm doing functional programming with F# at the moment and I'm quite stuck on this. I want to print out a string of text letter by letter without using a loop as that isn't considered functional. I have a very primitive way here:
printf "W"
Thread.Sleep(200)
printf "e"
Thread.Sleep(200)
printf "l"
Thread.Sleep(200)
printf "c"
Thread.Sleep(200)
printf "o"
Thread.Sleep(200)
printf "m"
Thread.Sleep(200)
printf "e "
but obviously, I cannot do that for a 150 character string. If anyone can provide some help or point me in the right direction, it would be most appreciative. Thanks
As mentioned in the comments, blocking a thread and printing are side-effects and so they are not really functional on their own. The nice thing about F# is that you can do side-effects easily if you need to. Typically, you will have some core functional logic, called from a bit of code that does the interaction with user using side-effects.
As you really just need to iterate over a word, for loop does this perfectly:
let msg = "Welcome"
for c in msg do
printf "%c" c
Thread.Sleep(200)
But since you asked about more functional ways, one thing you could learn using this example is recursion (which is quite important in functional programming in general). You can transform for loop into a recursive function like this:
let rec printChars chars =
match chars with
| [] -> ()
| c::rest ->
printfn "%c" c
Thread.Sleep(200)
printChars rest
let msg = "Welcome"
printChars (List.ofSeq msg)
This is not what I'd normally write - because there is no point making code more complicated - but it is useful learning exercise.
Okay so i'm currently making mastermind in console in fsharp, and im trying to figure out how to ask the user if they want to play again.
let main() =
choosePuzzleMaker()
puzzleGuess()
c <- guess b [([],(0,0))]
while a <> c && d <> 8 do
c <- guess b [(c, validate a c)]
d <- d+1
if d <> 8 then
printfn "GZ! FUCKING MASTERMIND! You completed in %A turns and the code was %A" d a
else
printfn "That didn't go well...?"
printfn "Game Over!"
PlayAgain()
main()
where i tried defining PlayAgain() as:
let rec PlayAgain() =
printfn "Do you want to play again? Please type:
1: Yes
2: No\n"
match System.Console.ReadLine() with
| "1"|"yes"|"Yes" -> printfn "Alright!!!"
choosePuzzleMaker()
| "2"|"no"|"No" -> printfn "The game is over!"
| _ -> printfn "Invalid option! Please try again!"
(PlayAgain())
However, that didn't work so my quesiton is:
How would you make the console take a response yes/no and make the program begin again?
It looks like your problem is a simple indentation mistake. F#, like Python, defines code blocks by indentation. Let me show you an example:
// Some variables
let x = 5
let y = 3
let z = 1
let add1_wrong x =
printfn "Adding 1 to %d produces..." x
printfn "The wrong answer: %d" (x + 1) // Oops! This is wrong
let add1_correct x =
printfn "Adding 1 to %d produces..." x
printfn "The right answer: %d" (x + 1) // This is correct
add1_wrong x
add1_wrong y
add1_wrong z
add1_correct x
add1_correct y
add1_correct z
Try running that in F# Interactive and you'll get the following output:
The wrong answer: 6
Adding 1 to 5 produces...
Adding 1 to 3 produces...
Adding 1 to 1 produces...
Adding 1 to 5 produces...
The right answer: 6
Adding 1 to 3 produces...
The right answer: 4
Adding 1 to 1 produces...
The right answer: 2
Notice how "The wrong answer: 6" was printed right away, before you ever called the add1_wrong function? The way the code is written, it looks like the author intended to put the printfn "The wrong answer" line inside the add1_wrong function, but he made an indentation mistake and put it outside the function instead. So it gets run at the same time as the rest of the code that sets the x, y, and z variables and calls add1_wrong and add1_right.
If you don't yet understand what's going on in that sample code, stop reading now and keep reading it until you understand it. (Or ask a followup question if you still don't understand it after two or three readthroughs, because that means that I haven't explained it very well). It's important that you see the indentation mistake in my sample code before proceeding, because the code you posted has the same mistake in it. Actually, you have two indentation mistakes, but only one of them is causing the problem you've asked us about.
Here's your main() function, exactly as you typed it in this question, with the two indentation mistakes in it:
let main() =
choosePuzzleMaker()
puzzleGuess()
c <- guess b [([],(0,0))]
while a <> c && d <> 8 do
c <- guess b [(c, validate a c)]
d <- d+1
if d <> 8 then
printfn "GZ! FUCKING MASTERMIND! You completed in %A turns and the code was %A" d a
else
printfn "That didn't go well...?"
printfn "Game Over!"
PlayAgain()
main()
And now, here's the same function, with both indentation mistakes solved:
let main() =
choosePuzzleMaker()
puzzleGuess()
c <- guess b [([],(0,0))]
while a <> c && d <> 8 do
c <- guess b [(c, validate a c)]
d <- d+1
if d <> 8 then
printfn "GZ! FUCKING MASTERMIND! You completed in %A turns and the code was %A" d a
else
printfn "That didn't go well...?"
printfn "Game Over!"
PlayAgain()
main()
The c <- guess b [([],(0,0))] line has been indented to match the other lines, and the PlayAgain() call at the end has been indented to be inside your main() function, instead of outside it the way you originally wrote it.
This is what Mark Seemann meant when he wrote in the comments that "the program only calls PlayAgain once". The way you wrote it, the PlayAgain function is not called at the end of main(). Instead, you were calling it once, then calling main() once, and then exiting your program.
By the way, there are lots of other things that I (and other experienced F# programmers) would suggest doing differently in your code -- for example, the names a, b, c and d aren't good names, because they don't give you a clue about what's supposed to be in those names. I'd suggest renaming them as follows:
a should be called correctAnswer
b should be called... actually, I haven't a clue what b is. I know it's passed into the guess function, but I have no idea how it gets used. And that, by the way, is why it's a bad variable name. Even if I don't see any code that uses it, the name alone should give me a clue as to how it's intended to be used.
c should be called thisGuess
d should be called rounds or numberOfGuesses.
Hope that helps you figure out (and fix) your mistake. Let us know if you need further help.
UPDATE: To answer your latest comment, there's a simple solution to your problem, and a clever solution. I'll show you both, because the clever solution will teach you a very valuable programming technique that's used all the time in functional programming languages like F#.
First, the simple solution. In F#, if you need to have two functions that call each other, that's called mutual recursion, and there are two keywords that you'd use to support it: the rec and and keywords. It looks like this:
// Note that these two functions would form an infinite loop!
let rec f x =
g (x + 1)
and g x =
f (x * 2)
The rec keyword tells the F# compiler "The function I'm defining is going to be calling itself, directly or indirectly, at some point -- so please make its name available within the function itself." The and keyword creates a group of functions that all have their names available to each other.
So one way you could solve this is to do the following:
let rec PlayAgain() =
// ...
and main() =
// ...
That would work, but I recommend a second solution. One of the key ideas in functional programming is treating functions as "things" that you can manipulate. That is, you can store functions in lists or arrays, pass them as parameters to other functions, and so on. Which brings us to a very powerful technique for taking a function like your PlayAgain function, and making it more general and re-useable. If a function like PlayAgain has the general structure "Do some calculations or make a decision. Then, depending on what the results were, either do A or B next" -- then what you do is make A and B parameters of the function! In other words, you turn it from a function that takes no parameters into a function that takes one or two parameters, where the parameters are the "what to do next" functions. (Normally you'd take two parameters in a function that decides between two scenarios. But in the case of your PlayAgain function, one of the two "what to do next" steps is "do nothing", so it makes sense to have it take only one parameter). This is known as continuation-passing style -- "continuation" is the traditional functional-programming terminology for any "what to do next" step.
Here's what that would look like:
let rec PlayAgain whatToDoNext =
printfn "Do you want to play again? Please type:
1: Yes
2: No\n"
match System.Console.ReadLine() with
| "1"|"yes"|"Yes" -> printfn "Alright!!!"
whatToDoNext()
| "2"|"no"|"No" -> printfn "The game is over!"
| _ -> printfn "Invalid option! Please try again!"
(PlayAgain())
That's it! All I did was give PlayAgain a parameter, and then call that parameter in the appropriate place. Now we rewrite your main() function as follows (changing just the last line, and using let rec so that the name main will be available inside the main() function):
let rec main() =
choosePuzzleMaker()
puzzleGuess()
c <- guess b [([],(0,0))]
while a <> c && d <> 8 do
c <- guess b [(c, validate a c)]
d <- d+1
if d <> 8 then
printfn "GZ! FUCKING MASTERMIND! You completed in %A turns and the code was %A" d a
else
printfn "That didn't go well...?"
printfn "Game Over!"
PlayAgain main
And with that, you've avoided the use of and, and you've discovered a powerful new programming technique. I strongly recommend that F# beginners avoid using the and keyword if possible, because it tends to add unnecessary complication to reading the code later. And, as in this case, it can often be avoided by simply making the "what to do next" step a parameter, which also means that the PlayAgain function will be more easily reused as-is in later programs.
It turns out that it is really hard to google the word comment.
Is is possible to represent "comment" expressions in quotations abstract syntax tree?
<# //this gets ignored by the compiler and don't inject the quotation
#>
If not, can you suggest a workaround to represent the comments?
As Ganesh points out, the Expr type has no way of representing comments - the F# quotations really represent just the AST of the expression, rather than full information about the source code (although you can get a file name & a location of a quoted expression).
To somehow embed comments in quotations, you'd need to come up with a way of embedding comments as valid F# code that means something - so you could e.g. define a dummy function comment and do something like this:
let comment (s:string) = ()
let sample =
<# comment "this is not ignored"
1 + ( comment "this is also not ignored"
4 ) #>
Then you could write an active pattern that looks for an expression of the form comment "..."; <expr> and extract the string and the following <expr>:
open Microsoft.FSharp.Quotations
let (|Comment|_|) = function
| Patterns.Sequential(DerivedPatterns.SpecificCall <## comment ##> (None, [], [Patterns.Value(comment, _)]), body) ->
Some(unbox<string> comment, body)
| _ -> None
Using the pattern, we can now write an (incomplete) pattern matching that succeeds when the top-level expression is some commented body expression:
match sample with
| Comment(comment, body) ->
printfn "// %s\n%A" comment body
This is not a very nice way of doing it, but I guess it is as good as it can get if you want to embed some annotations in a hand-written quotation code.
The Expr type that quotations return doesn't contain any way to represent a comment, so this is very unlikely to be possible.
When quoting
<# 1 + 1 #>
I want "1 + 1"
instead of
"Call (None, Int32 op_Addition[Int32,Int32,Int32](Int32, Int32),
[Value (1), Value (1)])"
You'll have to write it yourself. See the F# quotations visualizer code as a guide for transforming the quotations abstract syntax tree.
I have implemented a quotation decompiler as part of a larger open source project Unquote. It can decompile many simple F# quoted expressions as single-line non-light syntax strings (see the project's home page for a list of decompiler features). For example,
> decompile <# (11 + 3) / 2 = String.length ("hello world".Substring(4, 5)) #>;;
val it : string =
"(11 + 3) / 2 = String.length ("hello world".Substring(4, 5))"
#Kurt Schelfthout is correct about the many challenges faced when decompiling F# Quotations into human readable form. But from my work so far, I believe that it is possible to write a quotation decompiler which can generate correct F# code. Take match expressions and computation expressions for example, the Unquote decompiler can produce correct F# code in the following simple cases:
> decompile <# match true with | true -> "hi" | _ -> "bye" #>;;
val it : string =
"let matchValue = true in if matchValue then "hi" else "bye""
> decompile <# seq {yield 1; yield 2} #>;;
val it : string =
"seq (Seq.delay (fun unitVar -> Seq.append (Seq.singleton 1) (Seq.delay (fun unitVar -> Seq.singleton 2))))"
Infix and prefix operators are not too hard (as you can see in the first example), but source structure such as new lines and indentation is an interesting topic (though not terribly difficult, I think). However, single-line non-light syntax is sufficient for Unquote's requirements.
There is none, and it's not quite that easy, except in very simple cases. One of the main problems, for example, is the match construct. It is syntactic sugar for a whole bunch of if and switch statements (try printing a quotation with a match in, you'll see). Another one of those biggies are computation expressions, but I guess you could skip those at first.
Then there is a the rabbit hole of ambiguities you'll have to resolve, with conventions like the pipe operator starts a new line, let starts a new line, indentation, infix, prefix, special cases like the (::) operator and so forth.
All in all, doable, but not trivial. Sort of like decompiling.
I've just found something I'd call a quirk in F# and would like to know whether it's by design or by mistake and if it's by design, why is it so...
If you write any range expression where the first term is greater than the second term the returned sequence is empty. A look at reflector suggests this is by design, but I can't really find a reason why it would have to be so.
An example to reproduce it is:
[1..10] |> List.length
[10..1] |> List.length
The first will print out 10 while the second will print out 0.
Tests were made in F# CTP 1.9.6.2.
EDIT: thanks for suggesting expliciting the range, but there's still one case (which is what inspired me to ask this question) that won't be covered. What if A and B are variables and none is constantly greater than the other although they're always different?
Considering that the range expression does not seem to get optimized at compiled time anyway, is there any good reason for the code which determines the step (not explicitly specified) in case A and B are ints not to allow negative steps?
As suggested by other answers, you can do
[10 .. -1 .. 1] |> List.iter (printfn "%A")
e.g.
[start .. step .. stop]
Adam Wright - But you should be able
to change the binding for types you're
interested in to behave in any way you
like (including counting down if x >
y).
Taking Adam's suggestion into code:
let (..) a b =
if a < b then seq { a .. b }
else seq { a .. -1 .. b }
printfn "%A" (seq { 1 .. 10 })
printfn "%A" (seq { 10 .. 1 })
This works for int ranges. Have a look at the source code for (..): you may be able to use that to work over other types of ranges, but not sure how you would get the right value of -1 for your specific type.
What "should" happen is, of course, subjective. Normal range notation in my mind defines [x..y] as the set of all elements greater than or equal to x AND less than or equal to y; an empty set if y < x. In this case, we need to appeal to the F# spec.
Range expressions expr1 .. expr2 are evaluated as a call to the overloaded operator (..), whose default binding is defined in Microsoft.FSharp.Core.Operators. This generates an IEnumerable<_> for the range of values between the given start (expr1) and finish (expr2) values, using an increment of 1. The operator requires the existence of a static member (..) (long name GetRange) on the static type of expr1 with an appropriate signature.
Range expressions expr1 .. expr2 .. expr3 are evaluated as a call to the overloaded operator (.. ..), whose default binding is defined in Microsoft.FSharp.Core.Operators. This generates an IEnumerable<_> for the range of values between the given start (expr1) and finish (expr3) values, using an increment of expr2. The operator requires the existence of a static member (..) (long name GetRange) on the static type of expr1 with an appropriate signature.
The standard doesn't seem to define the .. operator (a least, that I can find). But you should be able to change the binding for types you're interested in to behave in any way you like (including counting down if x > y).
In haskell, you can write [10, 9 .. 1]. Perhaps it works the same in F# (I haven't tried it)?
edit:
It seems that the F# syntax is different, maybe something like [10..-1..1]
Ranges are generally expressed (in the languages and frameworks that support them) like this:
low_value <to> high_value
Can you give a good argument why a range ought to be able to be expressed differently? Since you were requesting a range from a higher number to a lower number does it not stand to reason that the resulting range would have no members?