Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 2 years ago.
Improve this question
Is there a more idiomatic way to print an index +1 value with F#?
let plusOne i = i + 1
let collection = [1..10]
collection |> List.iteri (fun index value -> printfn "%i %i" (plusOne index) value)
F# does have many special idioms but that doesn’t mean it breaks the very common idiom in which indices of list/array... start from zero.
So, to answer to question: no, F# does not have any special idiom for index plus.
However, if you are intending to often iter a list with index plus one, you can use Active Pattern to implicitly increase the index right in the parameter declaration, like this:
let (|Inc|) = (+) 1
let collection = [1..10]
collection |> List.iteri (fun (Inc i) value -> printfn "%i %i" i value)
Related
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 2 years ago.
Improve this question
I want to return second element of a list. And this input list can be any type. But I don't understand why my code does not work.
let test (x: int, y: list<'T>): 'T =
match y with
| [] -> 0
| h :: t -> h
test (1, ["a"; "b"; "c"])
test (1, [1; 2; 3])
Your code does not type check because your implementation restricts the type of the function test - it is not list<'T> as you specify, but rather just list<int>. You can see this in the warning that the compiler gives you on the line where you return 0:
warning FS0064: This construct causes code to be less generic than indicated by the type annotations. The type variable 'T has been constrained to be type 'int'.
The issue is that all branches of the match construct need to return the same type. If one returns an element of the list and the other 0, then the compiler infers that the list element must also be of type int.
If the function is supposed to work on shorter lists, you could return an option type instead. If it is not, you could throw an exception. A version with exception looks like this:
let test (x: int, y: list<'T>): 'T =
match y with
| [] -> failwith "Not enough elements"
| h :: t -> h
test (1, ["a"; "b"; "c"]) // Returns "a"
test (1, [1; 2; 3]) // Returns 1
This now runs and returns the first element of the list. Hopefuly, this is enough advice to let you continue figuring things out! To return third element, you'll need to make the function recursive using let rec and make it call itself in the h :: t case. I'm not going to show the solution, because I assume you're learning F# and this is a good problem to work on.
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 7 years ago.
Improve this question
I have the following definition in a parser using the Haskell ReadP library:
expr = chainl1 comp (string "===" >> return fun6)
How can I skip spaces before the === operator? I don't know how to include it in this syntax.
ReadP has skipSpaces for exactly that usecase; your parser then becomes
expr = chainl1 comp (skipSpaces >> string "===" >> return fun6)
Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 7 years ago.
Improve this question
I tried F# under command line, it doesn't recognize function definition
> let ref f n=
- if(n<=2)then 1
- else f(n-1)+f(n-2)
- ;;
val ref : f:(int -> int) -> n:int -> int
> printf "%i" (f 10)
- ;;
printf "%i" (f 10)
-------------^
stdin(9,14): error FS0039: The value or constructor 'f' is not defined
Question: any error in my program? I copied and pasted the definition and usage of f into visual studio's F# project, it runs OK.
But Why command line fails?
You defined a function named ref, but you're trying to call a function named f. No such function was defined (though your ref function takes a parameter named f), so you can't call it.
You probably intended to define a recursive function f using the rec keyword (with a 'c'), rather than defining a function named ref.
I copied and pasted the definition and usage of f into visual studio's F# project, it runs OK.
That's only possible if your VS project already contains a definition of a function named f.
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 8 years ago.
Improve this question
When passing a function to another function which should calculate the result and then pass that value as an argument to another function, I've discovered that I could "compose" the following code in 5 different ways.
let testnum testFun =
testFun 4
printfn "result: %b" (testnum (=) 0)
printfn "result: %b" <| testnum (<) 0
printfn "result: %b" (testnum <| (>=) 0)
testnum <| (=) 0 |> printfn "result: %b"
printfn "resutl: %b" << testnum <| (<>) 0
I do like the style without parentheses more but now I'm wondering, is there a preferred style assuming my goal is readability and supportability of my code?
For your example I would have picked the first one:
printfn "result: %b" (testnum (=) 0)
The second one is passable:
printfn "result: %b" <| testnum (<) 0
The others are too contrived, they look like exercise in obfuscation.
I do use "backward" pipe operator exclusively in two situations:
when I have a type constructor that would need nested parentheses otherwise, so Some <| Foo ("bar", "baz") instead of Some (Foo ("bar", "baz"))
when I want to pass a single anonymous function as a last argument - it communicates nicely where the action is at:
lock sync <| fun () ->
...
For what is worth, if there are multiple anonymous functions passed as arguments, I would usually parenthesize each one of them instead (the notable exception being when one of them is a few characters long one liner and the other has multiple lines - then I would still go with the above syntax).
As for pipelining, I would usually go with |> for longer pipelines, and use function composition >> for shorter ones, when I don't need to refer to the argument again in the body of the function.
I don't think I would ever put |> and <| in the same line without parenthesizing one of them. It just looks odd.
Prefer pipe |>, this help with inference and readability
(=) 3 |> testnum |> printfn "result: %b"
you can easy break it on multiple lines
(=) 3
|> testnum
|> printfn "result: %b"
if arguments are few, you can pass them directly
testnum (=) 4 |> printfn "result: %b"
but use pipe |> or composition >> like g x |> f or x |> g |> f instead of nested function call f(g(x)), is more idiomatic. This also help with inference, for example instead of the . operator
open System.Linq
let double x = x * 2
let double1 items = items |> Seq.map double
[1;2;3] |> double1 |> printfn "%A"
//this doesn't compile,
//error: Lookup on object of indeterminate type based on information prior to this program point. A type annotation may be needed ..
//
// let double2 items = items.Select(double)
// [1;2;3] |> double2 |> printfn "%A"
let double3 (items:seq<_>) = items.Select(double)
[1;2;3] |> double3 |> printfn "%A"
example: https://dotnetfiddle.net/K0u3NQ
As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 10 years ago.
I've been reading F# core library sources (v.2.0) and found something rather interesting:
List.foldBack is implemented via a mutable Array, unlike List.fold which is pretty straightforward. Here's the source or you may find it here:
let foldArraySubRight (f:OptimizedClosures.FSharpFunc<'T,_,_>) (arr: 'T[]) start fin acc =
let mutable state = acc
for i = fin downto start do
state <- f.Invoke(arr.[i], state)
state
// this version doesn't causes stack overflow - it uses a private stack
let foldBack<'T,'State> f (list:'T list) (acc:'State) =
// skipped optimized implementations for known lists
// It is faster to allocate and iterate an array than to create all those
// highly nested stacks. It also means we won't get stack overflows here.
let arr = toArray list
let arrn = arr.Length
foldArraySubRight f arr 0 (arrn - 1) acc
What is the reason not to use continuation?
Something naive like the code below seems to work only 2-3 times slower than the highly optimized library method. It seems questionable that it is really "faster to allocate and iterate an array". Also, it is tail recursive, so no StackOverflow here.
Am I missing something?
let foldBack2 predicate acc list =
let rec loop list cont =
match list with
| [] -> cont acc
| h::t -> loop t (fun racc -> cont (predicate h racc))
loop list id
I can think of a few reasons not to use CPS:
you trade memory for stack space (all those continuations live on the heap)
CPS is inscrutable to most people
as you discovered, it's generally slower than the alternatives (see this question for evidence)
A list can't be easily traversed backward and since arrays can't be beat for sequential access (forward or backward) copying to/from an array is actually pretty efficient. As a challenge, try writing a faster foldBack for 10,000/100,000/100,000,000 elements.
Make the common case fast.
In practice, you often deal with small lists which do not cause stack overflow anyway. As an example, the counterpart of F#'s List.foldBack in OCaml, List.fold_right, isn't tail-recursive or using CPS either.
As users, we don't really care what is the internal implementation. We enjoy the surprise of having both fast and tail-recursive List.foldBack. For instance, this beautiful split function is tail-recursive in F#:
let split list = List.foldBack (fun x (l,r) -> x::r, l) list ([],[])