In F#, you can say
let x = {1..5}
and you get the expected {1,2,3,4,5}. But if you say
let y = {5..1}
, you get an empty sequence.
I assume this is done to make it easier to return empty sequences if, i.e., the start and stop are variables and you're already past the limit. But what is the best way to concisely define a decreasing sequence?
Right now I'm doing this:
List.rev {1..10000}
...but there's got to be a better way.
You can specify the increment:
let x = { 5 .. -1 .. 1 }
Related
getting an error when I try to run this line of code and I can't figure out why
let validCol column value : bool =
for i in 0..8 do
if sudokuBoard.[i,column] = value then
false
else true
As Tyler Hartwig says a for loop cannot return a value except unit.
On the other hand, inside a list comprehension or a seq Computation Expression you can use for to yield the values and then test if the one you are looking for exists:
let validCol column value : bool =
seq { for i in 0..8 do yield sudokuBoard.[i,column] }
|> Seq.exists value
|> not
In F#, the last call made is what is returned, you have explicitly declared you are returning a bool.
The for loop is unable to return or aggregate multiple values, bun instead, returns unit.
let validCol column value : bool =
for i in 0..8 do
if sudokuBoard.[i,column] = value then
false
else
true
Here, you'll need to figure out how to aggregate all the bool to get your final result. I'm not quite sure what this is supposed to return, or I'd give an example.
It looks like you are looking for a short-cut out of the loop like in C# you can use continue, break or return to exit a loop.
In F# the way to accomplish that with performance is to use tail-recursion. You could achieve it with while loops but that requires mutable variables which tail-recursion doesn't need (although we sometimes uses it).
A tail-recursive function is one that calls itself at the very end and doesn't look at the result:
So this is tail-recursive
let rec loop acc i = if i > 0 then loop (acc + i) (i - 1) else acc
Where this isn't
let rec loop fib i = if i < 1 then 1 else fib (i - 1) + fib (i - 2)
If F# compiler determines a function is tail-recursive the compiler applies tail-recursion optimization (TCO) on the function, basically it unrolls it into an efficient for loop that looks a lot like the loop would like in C#.
So here is one way to write validCol using tail-recursion:
let validCol column value : bool =
// loops is tail-recursive
let rec loop column value i =
if i < 9 then
if sudokuBoard.[i,column] = value then
false // The value already exists in the column, not valid
else
loop column value (i + 1) // Check next row.
else
true // Reach the end, the value is valid
loop column value 0
Unfortunately; F# compiler doesn't have an attribute to force TCO (like Scala or kotlin does) and therefore if you make a slight mistake you might end up with a function that isn't TCO. I think I saw GitHub issue about adding such an attribute.
PS. seq comprehensions are nice in many cases but for a sudoku solver I assume you are looking for something that is as fast as possible. seq comprehensions (and LINQ) I think adds too much overhead for a sudoku solver whereas tail-recursion is about as quick as you can get in F#.
PS. In .NET 2D arrays are slower than 1D arrays, just FYI. Unsure if it has improved with dotnet core.
// Standard pattern matching.
let Foo x =
match x with
| 1 ->
// ... lots of code, only evaluated if x == 1
| 2 ->
// ... lots of code, only evaluated if x == 2
// Standard pattern matching separated out, causing exception.
let Bar x =
let valueOne = //... lots of code, evaluated always. Exception if value <> 1.
let valueTwo = //... lots of code, evaluated always. Exception if value <> 2.
match x with
| 1 -> valueOne
| 2 -> valueTwo
In a pattern matching using "match", the code for each pattern can be large, see Foo above, making me want to split out the blocks as separate calls for improved readability.
The issue with this can be that the call will be evaluated even though the pattern is not matched, as in Bar above.
Option 1: lazy eval.
Option 2: forward the argument/parameters.
Option 3: forward the argument/parameters and use Active pattern.
What is the preferred method for improving the readability where code under each pattern can be large. Or are there any other obvious solution to the problem?
// ===== OPTION 1 =====
// Pattern matching separated out, lazy eval.
let Foo x =
let valueOne = lazy //... lots of code, evaluated on Force().
let valueTwo = lazy //... lots of code, evaluated on Force().
match x with
| 1 -> valueOne.Force()
| 2 -> valueTwo.Force()
// ===== OPTION 2 =====
// Pattern matching separated out, with arguments.
let Foo x =
let valueOne a = //... lots of code.
let valueTwo a = //... lots of code.
match x with
| 1 -> valueOne x
| 2 -> valueTwo x
// ===== OPTION 3 =====
// Active Pattern matching separated out, with arguments.
let Foo x =
let (|ValueOne|_|) inp =
if inp = 1 then Some(...) else None
let (|ValueTwo|_|) inp =
if inp = 2 then Some(...) else None
match x with
| ValueOne a -> a
| ValueTwo b -> b
I would probably just extract the two bodies of the pattern matching into functions that take unit:
let caseOne () =
// Lots of code when x=1
let caseTwo () =
// Lots of code when x=2
let Foo x =
match x with
| 1 -> caseOne()
| 2 -> caseTwo()
This is similar to your solution using lazy, but as we are never re-using the result of the lazy value, there is really no reason for using lazy values - a function is simpler and it also delays the evaluation of the body.
If you then find that there is some commonality between caseOne and caseTwo, you can again extract this into another function that both of them can call.
Generally speaking, I try to have the semantics of my code match the logic of what I'm trying to accomplish. In your case, I would describe your problem as:
There are two different pieces of simple data I may receive. Based on which
one I receive, run a specific piece of code.
This maps exactly to option 2. I may or may not nest the functions like you have depending on the context. The other two options create a mismatch between your goal and your code.
Option 1:
I would describe the logic of this one as:
I have information (or context) now from which I can build two different calculations, one of which may need to be run later. Construct both now, and then evaluate the one which is needed later.
This really doesn't match the logic of what you want since there is no change in context or available data. You're still in the same context either way, so the additional complexity of making it lazy simply obfuscates the logic of the function.
Option 3:
I would describe the logic of this one as:
I have some data which may fit into one of two cases. Determining which case holds requires some complex logic, and that logic may also have some overlap with the logic needed to determine the needed return value of the overall function. Move the logic to determine the case into a separate function (an active pattern in this case), and then use the return value of the active pattern to determine the resulting value of the function.
This one conflates the control flow (determining what code should I execute next) with the logic executed in each case. Its much more clear to separate control flow from the following logic if there is no overlap between the two.
So match the structure of your code to the structure of your problem, or you'll end up with people wondering what the additional code complexity accomplishes.
Extremely just-started-yesterday new to F#.
What I want: To write code that parses the string "2 + 2" into (using as an example code from the tutorial project) Expr.Add(Expr.Num 2, Expr.Num 2) for evaluation. Some help to at least point me in the right direction or tell me it's too complex for my first F# project. (This is how I learn things: By bashing my head against stuff that's hard)
What I have: My best guess at code to extract the numbers. Probably horribly off base. Also, a lack of clue.
let script = "2 + 2";
let rec scriptParse xs =
match xs with
| [] -> (double)0
| y::ys -> (double)y
let split = (script.Split([|' '|]))
let f x = (split[x]) // "This code is not a function and cannot be applied."
let list = [ for x in 0..script.Length -> f x ]
let result = scriptParse
Thanks.
The immediate issue that you're running into is that split is an array of strings. To access an element of this array, the syntax is split.[x], not split[x] (which would apply split to the singleton list [x], assuming it were a function).
Here are a few other issues:
Your definition of list is probably wrong: x ranges up to the length of script, not the length of the array split. If you want to convert an array or other sequence to a list you can just use List.ofSeq or Seq.toList instead of an explicit list comprehension [...].
Your "casts" to double are a bit odd - that's not the right syntax for performing conversions in F#, although it will work in this case. double is a function, so the parentheses are unnecessary and what you are doing is really calling double 0 and double y. You should just use 0.0 for the first case, and in the second case, it's unclear what you are converting from.
In general, it would probably be better to do a bit more design up front to decide what your overall strategy will be, since it's not clear to me that you'll be able to piece together a working parser based on your current approach. There are several well known techniques for writing a parser - are you trying to use a particular approach?
I'm just beginning F# so please be kind if this is basic.
I've read that a function marked lazy is evaluated only once and then cached. For example:
let lazyFunc = lazy (1 + 1)
let theValue = Lazy.force lazyFunc
Compared to this version which would actually run each time it's called:
let eagerFunc = (1 + 1)
let theValue = eagerFunc
Based on that, should all functions be made lazy? When would you not want to? This is coming from material in the book "Beginning F#".
First of all, it may be helpful to note that none of the things you have defined is a function - eagerFunc and theValue are values of type int and lazyFunc is a value of type Lazy<int>. Given
let lazyTwo = lazy (1 + 1)
and
let eagerTwo = 1 + 1
the expression 1 + 1 will not be evaluated more than once no matter how many times you use eagerTwo. The difference is that 1 + 1 will be evaluated exactly once when defining eagerTwo, but will be evaluated at most once when lazyTwo is used (it will be evaluated the first time that the Value property is accessed, and then cached so that further uses of Value do not need to recalculated it). If lazyTwo's Value is never accessed, then its body 1 + 1 will never be evaluated.
Typically, you won't see much benefit to using lazy values in a strict language like F#. They add a small amount of overhead since accessing the Value property requires checking whether the value has already been calculated. They might save you a bit of calculation if you have something like let lazyValue = lazy someVeryExpensiveCalculationThatMightNotBeNeeded(), since the expensive calculation will only take place if the value is actually used. They can also make some algorithms terminate which otherwise would not, but this is not a major issue in F#. For instance:
// throws an exception if x = 0.0
let eagerDivision x =
let oneOverX = 1.0 / x
if x = 0.0 then
printfn "Tried to divide by zero" // too late, this line is never reached
else
printfn "One over x is: %f" oneOverX
// succeeds even if x = 0.0, since the quotient is lazily evaluated
let lazyDivision x =
let oneOverX = lazy (1.0 / x)
if x = 0.0 then
printfn "Tried to divide by zero"
else
printfn "One over x is: %f" oneOverX.Value
If function executions have side-effects and it is important to see the side-effects each time the function is called (say it wraps an I/O function) you would not want it to be lazy.
There are also functions that are so trivial that executing them each time is faster than caching the value--
let eagerFunc = (1 + 1) is a let binding, and will only execute once. let eagerFunc() = (1 + 1) is a function accepting unit (nothing) and returning an int. It will execute each time it's called. In a sense, every function is lazy, that is, it only executes when called. However, the lazy keyword (and System.Lazy, which it returns) will execute the expression/function given to it at most once. Subsequent calls to the Value property will return the cached result. This is useful when computation of the value is expensive.
Many functions will not be suitable for use with lazy because they are either non-deterministic (may return a different result with each invocation) or parameterized. Of course, it's possible to use a fully-applied (a value is supplied for each parameter) version of such functions, but generally the variability is desired.
For learning purposes I am trying out running a simulation as a sequence with F#. Starting from a sequence of random numbers, map is a straightforward way to generate a sequence of states if the states do not depend on the previous states. Where I run into a problem is when I try to do something like:
State(i+1) = F (State(i), random number)
I managed to get something working by using unfold, passing in the random generator along the lines of
let unfold (day:State,rnd:Random) =
let rand = rnd.NextDouble()
let nextDay = NextState day rand
Some (nextDay, (nextDay, rnd))
However, at least to my inexperienced eyes, something about passing around the Random instance seems fishy. Is there a way to achieve something similar but passing in a sequence of random numbers, rather than the generator?
I think your hunch about passing around a Random instance as being fishy is fair: when mutable state is useful it's a good idea to isolate it, so that you benifit from purity as much as possible.
We can isolate the state here by creating a sequence which yields a different set of random numbers upon each iteration
open System
let rndSeq =
seq {
//note that by putting rnd inside seq expression here, we ensure that each iteration of the sequence
//yields a different sequnce of random numbers
let rnd = new Random()
while true do yield rnd.NextDouble()
}
then, you can use Seq.scan to iterate the random sequence by mapping elements using a function which is informed by the previous element which was mapped.
let runSimulation inputSeq initialState =
inputSeq
|> Seq.scan
(fun (previousState:State) (inputElement:float) -> NextState previousState inputElement)
initialState
runSimulation rndSeq initialState //run the simulation using a random sequence of doubles greater than or equal to 0.0 and less than 1
You can see as an added bonus here that your simulated input and simulation implementation are no longer bound together, you can run your simulation using any input sequence.
I'd agree with BrokenGlass that using a global Random instance feels allright in this case. This is a reasonably localized use of mutable state, so it shouldn't be confusing.
As an alternative to unfold, you can consider writing the computation explicitly:
let simulationStates =
let rnd = new Random()
let rec generate (day:State) = seq {
let rand = rnd.NextDouble()
let nextDay = NextState day rand
yield nextDay
yield! generate nextDay }
generate InitialState
Note that the rnd value is local variable with a scope limited only to the definition of simulationStates. This is quite nice way to keep mutable state separate from the rest of the program.
The version using unfold is probably more succinct; this one may be easier to read, so it depends on your personal style preferences.
Might be against the spirit, but I would just use a global Random instance in this case - alternatively you could define a sequence of random numbers like this:
let randomNumbers =
seq {
let rnd = new Random();
while true do
yield rnd.NextDouble();
}