I'm new to F# and I had trouble searching for the .. operator. Can someone explain why this function works?
let oddsUnderN n = seq {for i in 1 .. 2 .. n -> i}
How do multiple .. operators work?
This is a sequence expression and is used to specify the starting value, increment and end value of the sequence. In this case the starting value is 1, end is n and increment is 2.
Actually, the variable your assigning, oddsUnderN is a great clue as to what that loop will produce. That syntax allows you to skip every other element in the sequence, returning just the odd numbers.
So if n = 10 then your i would in turn equal:
1 3 5 7 9
So in the loop syntax of for i in x .. y .. z do:
x is the starting value
y is the incrementing value
z is the final value
In other words. This expression
for i in 1 .. 10 do
...is shorthand for:
for i in 1 .. 1 .. 10 do
Related
I've just been doing some validation on value to see it is a product of three. Great use the modulus function. I want to pipe to it. Great use a partial application. But apparently not.
This is an example from my fsi in vs code.
> 27 % 3
-
- ;;
val it : int = 0
> (%) 3 27
- ;;
val it : int = 3
I really didn't expect to get a different result from an infix vs a partial.
Here is the operation in a pipe for context:
...
|> Seq.length // 27
|> (%) 3 // 3
Because you have the operands flipped. (%) 3 27 actually means 3 % 27, not 27 % 3, i.e. you want (%) 27 3.
Partial application of an infix doesn't work as I expected. The statement in my qustion is incorrect and this isn't a bug. It might be a fairly common missunderstanding for beginers so its worth a good explaination.
(%) x y = x % y
Therefore
(%) 27 3
= 27 % 3
= 0
The confusion comes when piping in the final value, the y.
you should not expect
y
|> (%) x
to result in
y % x
but rather
x % y
This is a little bit confusing particularly if you have used an infix operator, which does treats inputs symetrically (e.g +,=,<>,*), without questioning too deeply. You must take care that order of values supplied to an infix opperator are correct, even if it looks right at first inspection.
The clearest and most verbose way to handle an infix opperator, which accepts values in the opposite order to which you wish to supply them, is to just write out a lambda. However, there is also the option to back pipe '<|'.
Here is a snippet of code which was causing me a bug due to my misuse of the partially applied infix.
...
|> Seq.length // 27
|> (%) 3 // 3 % 27 = 3
It could be written with a backpipe to perform as expected
...
|> Seq.length // 27
|> (%) <|3 // 27 % 3 = 0
or more clearly with a lambda
...
|> Seq.length // 27
|> (fun x -> x % 3 // 27 % 3 = 0
The function I have:
let increment n = n+1;;
My call to the function:
let x = increment -5;;
The error I get:
let x = increment -5;;
^^^^^^^^^
Error: This expression has type int -> int
but an expression was expected of type int`
Why doesn't x = -4 after the function call?
I tried finding the answer myself and I ended up here:
http://caml.inria.fr/pub/docs/manual-ocaml-4.00/lex.html#prefix-symbol
The term "longest match rule" is used in the section Ambiguities, I assume that a clarification of that term would solve my issue?
The problem is easy, - is considered here as the binary operator minus so OCaml is reading it as increment minus 5 (increment and 5 are the two operands) when what you'd want is increment the number (minus 5) (increment being a function).
Just write increment (-5) and the job's done.
An alternative to using parentheses, as suggested in the other answer, is to use the ## application operator, e.g.:
let increment n = n + 1
let x = increment ## -5
Briefly, f ## x is the same as f x, but the ## operator has lower precdence than arithmetic operations, while function application has higher precedence. Thus, using the application operator allows you to omit parentheses.
Sometimes, the reverse application operator |> can be more idiomatic; it is typically used to "pipe" an expression through one or more function applications.
Example:
let increment n = n + 1
let x = -5 |> increment
let clamp x low high = x |> min high |> max low
So I have a program that, currently, finds the fibonacci equivalent of a user inputted value, e.g. 6 would be 5 (or 13 depending on whether or not you start with a 0). Personally I prefer the sequence starting with 0.
open System
let rec fib (n1 : bigint) (n2 : bigint) c =
if c = 1 then
n2
else
fib n2 (n1+n2) (c-1);;
let GetFib n =
(fib 1I 1I n);;
let input = Console.ReadLine()
Console.WriteLine(GetFib (Int32.Parse input))
The problem is that ALL it does is find the equivalent number in the sequence. I am trying to get it to print out all the values up to that user inputted value, e.g. 6 would print out 0,1,1,2,3,5. If anyone could help me figure out how to print out the whole sequence, that would be very helpful. Also if anyone can look at my code and tell me how to make it start at 0 when printing out the whole sequence, that would also be very much appreciated.
Thank you in advance for any help.
Take a look at the link s952163 gave you in the comments - that shows ways of generating a fibonnaci sequence using Seq expressions and also explains why these are useful.
The following will print a sequence up until the specified sequence number:
let fibsTo n = Seq.unfold (fun (m,n) -> Some (m, (n,n+m))) (0I,1I)
|>Seq.takeWhile (fun x -> x <= n)
let input = Console.ReadLine()
(fibsTo (Numerics.BigInteger.Parse input))|>Seq.iter(printfn "%A")
Note the use of printfn rather than console.writeline, the former is more idiomatic.
Also, you may want to consider handling negative inputs here as these will throw an error.
I'm working on creating maxima functions to simplify the del operator on vectors. How can I pass a list/vector to a function in maxima? This works:
(%i7) dot(a,b) := a[1]*b[1]+a[2]*b[2]+a[3]*b[3];
(%o7) dot(a, b) := a b + a b + a b
1 1 2 2 3 3
(%i8) dot(a,b);
2
(%o8) 3 x y - 4 x
but this doesn't:
(%i13) grad(a) := diff(a[1],x) + diff(a[2],y) + diff(a[3],z);
define: argument cannot be an atom or a subscripted memoizing function; found:
a
-- an error. To debug this try: debugmode(true);
Maxima has extremely confusing rules about scope and subscripts. First of all, I'll apologize for that.
My guess is that you already have an array named a by the time you define grad. Try a different name for the argument of grad -- try something which you haven't used yet. Does it work that way?
Anyway, shouldn't the definition be:
grad(a) := [diff(a, x), diff(a, y), diff(a, z)];
??
as we know that variables can't be variable in erlang. but consider this code,why each value of [1,2,3,4] is sequentially pattern matched to N,and don't throw exception??
1> [2*N || N <- [1,2,3,4]].
[2,4,6,8]
Saying that a variable can't be variable isn't quite true. It's more that a variable can only be assigned once. So the following psuedo-code is illegal:
N = 4;
foo(N);
N = N + 1;
foo(N);
However, the following is legal:
fact(0) -> 1,
fact(N) -> N * fact(N-1).
When we call fact(4) N will take the value 4 then 3 then 2 then 1 for each different function call. The code you are showing above is similar. For each item in the list N takes on a different value. But you never assigned the value of N more than once.