I thought it would make more sense to use match expressions in F# rather than while loops and if statements, but I can't get it to work. The code looks fine to me and I get no errors. Could somebody explain why it doesn't work, please?
open System
let width = Console.WindowWidth
let height = Console.WindowHeight
let rec main() =
let x = Console.CursorLeft
let y = Console.CursorTop
match Console.ReadKey().Key with
| ConsoleKey.UpArrow -> Console.SetCursorPosition(x, (y - 1))
| ConsoleKey.RightArrow -> Console.SetCursorPosition((x + 1), y)
| ConsoleKey.DownArrow -> Console.SetCursorPosition(x, (y + 1))
| ConsoleKey.LeftArrow -> Console.SetCursorPosition((x - 1), y)
| _ -> main()
main()
Console.ReadKey() |> ignore
The problem you're having is that after defining the main() function, you don't ever call it.
Here's what your code looks like right now:
let rec main() =
// The definition of main()
Console.ReadKey() |> ignore
Remember that in F#, indentation is significant: after a let someName = declaration, the rest of the next indented block is the body of the function. So there are just two top-level expressions in your code: one that defines a function called main() that is never called, and another one that reads a key from the console. In F#, there's nothing special about naming a function main(). To make a function the entry point to your program (the first thing to be run when your program is run), you need to declare it with the EntryPoint attribute:
[<EntryPoint>]
let rec main() =
// The definition of main()
Also take note of what the docs say about implicit entry points:
When a program has no EntryPoint attribute that explicitly indicates the entry point, the top level bindings in the last file to be compiled are used as the entry point.
The "top level bindings" in the program that you've shown us do two things: define a function, then read a key.
Put the EntryPoint attribute before your let rec main() = line and I suspect that will fix your problem. Or if you're running this as an .fsx script, then [<EntryPoint>] isn't the right approach, and you instead need to put a call to main() in the top-level part of the program (after it's been defined).
Related
It is actually pretty unxpected to me but consider this snippet in F#:
let f x =
printfn $"{x}"
fun x' -> x'
let y<'t> = f 1 //> val y<'t> : (obj -> obj)
y 2
//>
//1
//val it: obj = 2
what I would expect is that it will print "1" only when you bind f 1 to "y" (and that would tell me that "f" body only executes once) but seem like it executes "f" body on the every call of "y". Is it unavoidable effect related to auto curring or I'm missing something and there is a way to bypass outer function body execution on the every call of the returned function?
The hint as to what's going on here is the fact that 't has been constrained to obj and the signature of y is (obj -> obj). That's the F# compiler effectively say, "I give up, these have no real types, it is whatever it is" and emitting something that can execute at runtime but without any real type safety.
A side effect of this is that because it can't "pin down" y to a known signature, it cannot evaluate f, so it just emits y as a direct call to f, since you've effectively told the compiler that this is fine by parameterizing it with 't (which ends up just being obj, or "whatever").
Why is this happening? Value restriction!
I suspect you've evaluated this in F# Interactive block-by-block. The line of code that defines let y = f 1 is not possible to compile with more information. You can do so in two ways:
Use y with a real type that will pin its signature to the type you're using it as.
Give it an explicit signature like let y: int -> int = f 1 so that it's pinned down to a concrete type.
That's why if you execute this entire snippet in FSI or run it as a program, things work exactly like you'd expect:
let f x =
printfn $"{x}"
fun x' -> x'
let y = f 1
y 2
y 3
This is because y is generic.
Every time you refer to y, you choose a particular 't to go with that. For example:
let a = y<int>
let b = y<string>
a and b cannot be the same value, because they have been obtained from different instantiations of y. They have to be two different values. And this in turn means that y itself cannot be a single value. It has to be a function.
And that's what it is under the hood: it's compiled as a function, and every time you refer to it, the function is instantiated with the generic parameter you chose, and the body of the function is executed to obtain the result.
If you remove the generic parameter and give y a concrete type, the issue should go away:
let y = f 1 : obj -> obj
According to this previous answer
You could implement List.map like this:
let rec map project = function
| [] -> []
| head :: tail ->
project head :: map project tail ;;
but instead, it is implemented like this:
let rec map project = function
| [] -> []
| head :: tail ->
let result = project head in
result :: map project tail ;;
They say that it is done this way to make sure the projection function is called in the expected order in case it has side effects, e.g.
map print_int [1;2;3] ;;
should print 123, but the first implementation would print 321. However, when I test both of them myself in OCaml and F#, they produce exactly the same 123 result.
(Note that I am testing this in the OCaml and F# REPLs--Nick in the comments suggests this might be the cause of my inability to reproduce, but why?)
What am I misunderstanding? Can someone elaborate why they should produce different orders and how I can reproduce? This runs contrary to my previous understanding of OCaml code I've written in the past so this was surprising to me and I want to make sure not to repeat the mistake. When I read the two, I read it as exactly the same thing with an extraneous intermediary binding.
My only guess is that the order of expression evaluation using cons is right to left, but that seems very odd?
This is being done purely as research to better understand how OCaml executes code, I don't really need to create my own List.map for production code.
The point is that the order of function application in OCaml is unspecified, not that it will be in some specific undesired order.
When evaluating this expression:
project head :: map project tail
OCaml is allowed to evaluate project head first or it can evaluate map project tail first. Which one it chooses to do is unspecified. (In theory it would probably be admissible for the order to be different for different calls.) Since you want a specified order, you need to use the form with let.
The fact that the order is unspecified is documented in Section 6.7 of the OCaml manual. See the section Function application:
The order in which the expressions expr, argument1, …, argumentn are evaluated is not specified.
(The claim that the evaluation order is unspecified isn't something you can test. No number of cases of a particular order prove that that order is always going to be chosen.)
So when you have an implementation of map like this:
let rec map f = function
| [] -> []
| a::l -> f a :: map f l
none of the function applications (f a) within the map calls are guaranteed to be evaluated sequentially in the order you'd expect. So when you try this:
map print_int [1;2;3]
you get the output
321- : unit list = [(); (); ()]
since by the time those function applications weren't executed in a specific order.
Now when you implement the map like this:
let rec map f = function
| [] -> []
| a::l -> let r = f a in r :: map f l
you're forcing the function applications to be executed in the order you're expecting because you explicitly make a call to evaluate let r = f a.
So now when you try:
map print_int [1;2;3]
you will get
123- : unit list = [(); (); ()]
because you've explicitly made an effort to evaluate the function applications in order.
If I run the first example from MSDN (https://msdn.microsoft.com/en-us/library/dd233212.aspx) in the F# Interactive window, I get the expected output:
fun (x:System.Int32) -> x + 1
a + 1
let f = fun (x:System.Int32) -> x + 10 in f 10
But if I run it in the Main from my program, all let bindings are replaced by their constant values:
[<EntryPoint>]
let main argv =
let a = 2
// exprLambda has type "(int -> int)".
let exprLambda = <# fun x -> x + 1 #>
// exprCall has type unit.
let exprCall = <# a + 1 #>
println exprLambda
println exprCall
println <## let f x = x + 10 in f 10 ##>
Result:
fun (x:System.Int32) -> x + 1
2 + 1
let f = fun (x:System.Int32) -> x + 10 in f 10
Is this normal or a bug? Are the rules for this documented? What can I do to force it to the expected output?
Edit:
This answer (https://stackoverflow.com/a/4945137/1872399) states (Variables are automatically replaced with values if the variable is defined outside of the quotation). but I couldn't find any mention of this elsewhere.
Edit 2: What I really want to do
This code (https://gist.github.com/0x53A/8848b04c2250364a3c22) goes into the catch-all case and fails with not implemented:parseQuotation:Value (Variable "ax1") (I expected it to go into | Var(var) ->) so not only constants known at compile-time, but also function parameters are expanded to their values.
Edit 3:
I ran the working version (https://gist.github.com/0x53A/53f45949db812bde5d97) under the debugger, and it looks like that one is actually the bug:
The quotation is {Call (None, op_Addition, [PropertyGet (None, a, []), Value (1)])} witha = Program.a, so this seems to be a side-effect of the fact that let bindings in modules are compiled into properties. If I am correct, I should maybe file a doc-bug at Microsoft...
In general, the problem with quoting of variables is that they escape their scope. That is, having a variable foo in your quotation does not really make any sense if you do not have any way to find out what does the foo variable refer to.
So, for example, the following is OK, because the variable x is defined by the lambda:
<# fun x -> x #>
But if you have something like the following, it does not make sense to capture variable x because once the function returns, x is no longer in scope:
fun x -> <# x #>
This is the same to the situation you're describing - top-level bindings become static members of a module and so those can be captured, but local variables are not available after the expression evaluates and so they are replaced by values. So, the general rules are:
Accessing top-level bindings is quoted as getter of a static member
Accessing variables defined inside the quotations is captured as variable access
Accessing local variables of a function captures the value of the variable
There are definitely cases where being able to capture the variable name would be useful. One example that I really wanted to be able to do is to let people write for example:
plot(years, GDP)
The idea is that the plot function would get a quotation with variable names (which can then be used e.g. for plot axis). There is actually an F# 4.0 change proposal that lets you do this.
I'm starting out to learn Haskell. Even though I'm a dunce extraordinaire, I am intent on making this work. The error I received is listed as the title. This is the code that I wrote to try to implement the behavior of replicating a list (n) times and concatenating its new length as a new list. Now I have a basic understanding of how parsing works in Haskell, below my original code I will give example of some modified code to see if my understanding on parsing is adequate. My question for now is how I can properly indent or structure my block in order to not receive this error (is that specific enough :O) -- is there a piece of information I'm missing when it comes to creating instances and formatting? PLEASE DO NOT TELL ME OR OFFER SUGGESTIONS IF YOU NOTICE THAT MY CURRENT INSTANCE OR MAIN FUNCTION ARE SYNTACTICALLY WRONG. I want to figure it out and will deal with that GHC error when I get to it. (I hope that's the proper way to learn). BUT if I could ask for anyone's help in getting past this first obstacle in understanding proper formatting, I'd be grateful.
module Main where
import Data.List
n :: Int
x :: [Char]
instance Data stutter n x where
x = []
n = replicate >>= x : (n:xs)
stutter >>= main = concat [x:xs]
let stutter 6 "Iwannabehere" -- <-- parse error occurs here!!!
--Modified code with appropriate brackets, at least where I think they go.
module Main where
import Data.List
n :: Int
x :: [Char]
instance Data stutter n x where{
;x = []
;n = replicate >>= x : (n:xs)
;stutter >>= main = concat [x:xs]
;
};let stutter 6 "Iwannabehere" -- there should be no bracket of any kind at the end of this
I placed the 'let' expression on the outside of the block, I don't believe it goes inside and I also receive a parsing error if I do that. Not correct but I thought I'd ask anyway.
I'm not sure what the instance Data stutter n x is supposed to be, the instance XYZ where syntax is used solely for typeclasses, but you have a couple syntax errors here.
First of all, while GHC says that the error is on let stutter 6 "Iwannabehere", your first error occurs before that with stutter >>= main = concat [x:xs]. A single = sign is reserved for assignments, which are merely definitions. You can have assignments at the top level, inside a where block, or inside a let block (the where includes typeclass instance definitions). You can't have an assignment be part of an expression like x >>= y = z.
Your next syntax error is the let itself. let blocks can not appear at the top level, they only appear within another definition. You use let in GHCi but the reasons for that are outside the scope of this answer. Suffice to say that entering expression in GHCi is not equivalent to the top level of a source file.
Next, if you were to use a let block somewhere, it can only contain definitions. The syntax looks more like
let <name> [<args>] = <definition>
[<name> [<args>] = <definition>]
in <expression>
And this whole block makes an expression. For example, you could write
def f(x, y, z):
w = x + y + z
u = x - y - z
return w * u
in Python, and this would be equivalent to the Haskell function definition
f x y z = let w = x + y + z
u = x - y - z
in w * u
It only defines local variables. There is another form when you're using it inside do blocks where you can exclude the in <expression> part, such as
main = do
name <- getLine
let message = if length name > 5 then "short name" else "long name"
goodbye n = putStrLn ("Goodbye, " ++ n)
putStrLn message
goodbye name
Note that there is no need to use in here. You can if you want, it just means you have to start a new do block:
main = do
name <- getLine
let message = ...
goodbye n = ...
in do
putStrLn message
goodbye name
And this isn't as pretty.
Hopefully this points you more towards correct syntax, but it looks like you have some misunderstandings about how Haskell works. Have you looked at Learn You a Haskell? It's a pretty gentle and fun introduction to the language that can really help you learn the syntax and core ideas.
Your parse error is from the let keyword. Remove it and no error related to that will occur. let x = y is only relevant in GHCi and do-blocks, neither of which is relevant at this point. Essentially, just replace it with this line:
theWordIGet = stutter 6 "Iwannabehere"
Secondly, instance keyword in Haskell has absolutley nothing to do with what you want to do at this stage. This is not how Haskell functions are defined, which is what I'm guessing you want to do. This is what you're wanting to do to create a stutter function, assuming it simply repeats a string n times.
stutter :: Int -> String -> String
stutter n x = concat (replicate n x)
You'll also want to remove the type declarations for the (out-of-scope) values n and x: they're not objects, they're arguments for a function, which has its own signature determining the types of n and x within a function call.
Lastly, I imagine you will want to print the value of stutter 6 "Iwannabehere" when the program is executed. To do that, just add this:
main :: IO ()
main = print (stutter 6 "Iwannabehere")
In conclusion, I implore you to start from scratch and read 'Learn You a Haskell' online here, because you're going off in entirely the wrong direction - the program you've quoted is a jumble of expressions that could have a meaning, but are in the wrong place entirely. The book will show you the syntax of Haskell much better that I can write about in this one answer, and will explain fully how to make your program behave in the way you expect.
I'm new to f# and I tried to write a program supposed to go through all files in a given dir and for each file of type ".txt" to add an id number + "DONE" to the file.
my program:
//const:
[<Literal>]
let notImportantString= "blahBlah"
let mutable COUNT = 1.0
//funcs:
//addNumber --> add the sequence number COUNT to each file.
let addNumber (file : string) =
let mutable str = File.ReadAllText(file)
printfn "%s" str//just for check
let num = COUNT.ToString()
let str4 = str + " " + num + "\n\n\n DONE"
COUNT <- COUNT + 1.0
let str2 = File.WriteAllText(file,str4)
file
//matchFunc --> check if is ".txt"
let matchFunc (file : string) =
file.Contains(".txt")
//allFiles --> go through all files of a given dir
let allFiles dir =
seq
{ for file in Directory.GetFiles(dir) do
yield file
}
////////////////////////////
let dir = "D:\FSharpTesting"
let a = allFiles dir
|> Seq.filter(matchFunc)
|> Seq.map(addNumber)
printfn "%A" a
My question:
Tf I do not write the last line (printfn "%A" a) the files will not change.(if I DO write this line it works and change the files)
when I use debugger I see that it doesn't really computes the value of 'a' when it arrives to the line if "let a =......" it continues to the printfn line and than when it "sees" the 'a' there it goes back and computes the answer of 'a'.
why is it and how can i "start" the function without printing??
also- Can some one tells me why do I have to add file as a return type of the function "addNumber"?
(I added this because that how it works but I don't really understand why....)
last question-
if I write the COUNT variable right after the line of the [] definition
it gives an error and says that a constant cannot be "mutable" but if a add (and this is why I did so) another line before (like the string) it "forgets" the mistakes and works.
why that? and if you really cannot have a mutable const how can I do a static variable?
if I do not write the last line (printfn "%A" a) the files will not change.
F# sequences are lazy. So to force evaluation, you can execute some operation not returning a sequence. For example, you can call Seq.iter (have side effects, return ()), Seq.length (return an int which is the length of the sequence) or Seq.toList (return a list, an eager data structure), etc.
Can some one tells me why do I have to add file : string as a return type of the function "addNumber"?
Method and property access don't play nice with F# type inference. The type checker works from left to right, from top to bottom. When you say file.Contains, it doesn't know which type this should be with Contains member. Therefore, your type annotation is a good hint to F# type checker.
if I write the COUNT variable right after the line of the [<Literal>] definition
it gives an error and says that a constant cannot be "mutable"
Quoting from MSDN:
Values that are intended to be constants can be marked with the Literal attribute. This attribute has the effect of causing a value to be compiled as a constant.
A mutable value can change its value at some point in your program; the compiler complains for a good reason. You can simply delete [<Literal>] attribute.
To elaborate on Alex's answer -- F# sequences are lazily evaluated. This means that each element in the sequence is generated "on demand".
The benefit of this is that you don't waste computation time and memory on elements you don't ever need. Lazy evaluation does take a little getting used to though -- specifically because you can't assume order of execution (or that execution will even happen at all).
Your problem has a simple fix: just use Seq.iter to force execution/evaluation of the sequence, and pass the 'ignore' function to it since we don't care about the values returned by the sequence.
let a = allFiles dir
|> Seq.filter(matchFunc)
|> Seq.map(addNumber)
|> Seq.iter ignore // Forces the sequence to execute
Seq.map is intended to map one value to another, not generally to mutate a value. seq<_> represents a lazily generated sequence so, as Alex pointed out, nothing will happen until the sequence is enumerated. This is probably a better fit for codereview, but here's how I would write this:
Directory.EnumerateFiles(dir, "*.txt")
|> Seq.iteri (fun i path ->
let text = File.ReadAllText(path)
printfn "%s" text
let text = sprintf "%s %d\n\n\n DONE" text (i + 1)
File.WriteAllText(path, text))
Seq.map requires a return type, as do all expressions in F#. If a function performs an action, as opposed to computing a value, it can return unit: (). Regarding COUNT, a value cannot be mutable and [<Literal>] (const in C#). Those are precise opposites. For a static variable, use a module-scoped let mutable binding:
module Counter =
let mutable count = 1
open Counter
count <- count + 1
But you can avoid global mutable data by making count a function with a counter variable as a part of its private implementation. You can do this with a closure:
let count =
let i = ref 0
fun () ->
incr i
!i
let one = count()
let two = count()
f# is evaluated from top to bottom, but you are creating only lazy values until you do printfn. So, printfn is actually the first thing that gets executed which in turn executes the rest of your code. I think you can do the same thing if you tack on a println after Seq.map(addNumber) and do toList on it which will force evaluation as well.
This is a general behaviour of lazy sequence. you have the same in, say C# using IEnumerable, for which seq is an alias.
In pseudo code :
var lazyseq = "abcdef".Select(a => print a); //does not do anything
var b = lazyseq.ToArray(); //will evaluate the sequence
ToArray triggers the evaluation of a sequence :
This illustrate the fact that a sequence is just a description, and does not tell you when it will be enumerated : this is in control of the consumer of the sequence.
To go a bit further on the subject, you might want to look at this page from F# wikibook:
let isNebraskaCity_bad city =
let cities =
printfn "Creating cities Set"
["Bellevue"; "Omaha"; "Lincoln"; "Papillion"]
|> Set.ofList
cities.Contains(city)
let isNebraskaCity_good =
let cities =
printfn "Creating cities Set"
["Bellevue"; "Omaha"; "Lincoln"; "Papillion"]
|> Set.ofList
fun city -> cities.Contains(city)
Most notably, Sequence are not cached (although you can make them so). You see then that the dintinguo between the description and the runtime behaviour can have important consequence as the sequence itself is recomputed which can incur a very high cost and introduce quadratic number of operations if each value is itself linear to get !