This question already has answers here:
How to define printfn equivalent in F#
(2 answers)
Currying functions with format dependent types
(1 answer)
Closed 8 years ago.
I was trying to do the following:
let print = printf "%A"
print "Test"
print [1..10]
I got an error says the print function is expecting a string thus doesn't take [1..10]. Why doesn't this work?
Related
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)
This question already has an answer here:
What does a double exclamation mark (!!) in Fsharp / FAKE?
(1 answer)
Closed 4 years ago.
I'm looking at a FAKE build script that was auto-generated through an FsLab template. In front of one of the strings in a "let" binding, the !! operator is used. What is the meaning of the !! operator?
Looking on the Microsoft Docs F# Symbols and Operator Reference, the !! operator is not listed.
Here is the code in question, the !! operator is in the third-to-last line:
#r "./packages/build/FAKE/tools/FakeLib.dll"
open Fake
open System
let buildDir = "./build/"
let appReferences = !! "/**/*.fsproj"
let dotnetcliVersion = "2.0.2"
let mutable dotnetExePath = "dotnet"
Further down, the appReferences identifier is used as following:
Target "Restore" (fun _ ->
appReferences
|> Seq.iter (fun p ->
let dir = System.IO.Path.GetDirectoryName p
runDotnet dir "restore"
)
)
It takes file pattern and returns a collection of files matching the pattern.
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.
This question already has answers here:
How to write a function for generic numbers?
(5 answers)
Closed 8 years ago.
I am writing an assembly with some functionality that is intended to work with numeric primitives, i.e. float, int, decimal, etc.
One of the functions takes two sequences and calculates the running average of the two. An implementation for floats may look like this
let average x y = (x+y)/2.
let a = [1..10] |> List.map float
let b = List.rev [1..10] |> List.map float
let result = (a, b) ||> List.map2 average
How can I make this generic for numeric primitives?
F# has so called "static member constraints" that can be used for writing generic numerical code. This is limited to F# (because .NET has no concept like this).
In general, you need to mark the function as inline. This will make the standard operators inside the function behave as generic. In addition, you need to avoid using constants (like 2.0). You can typically replace them with some operation from the LanguagePrimitives module. For example, your average function can be written as generic using:
let inline average x y =
LanguagePrimitives.DivideByInt (x + y) 2
For more information check out this blog post about generic numeric computations in F#.
This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center.
Closed 11 years ago.
Want to convert some C# code for RX to F# code.
The following C# code works well:
var seqNum = Observable.Range(1, 5);
var seqString = from n in seqNum
select new string('*', (int)n);
seqString.Subscribe(str => { Console.WriteLine(str); });
Console.ReadKey();
The following is my code in F#:
#light
open System
open System.Collections.Generic
open System.Linq
open System.Reactive
open System.Reactive.Linq
open System.Reactive.Subjects
open System.Threading
open System.IO
let seqNum = Observable.Range(1, 5)
let seqString = from n in seqNum
select new string('*', (int)n)
Console.ReadLine() |> ignore
But I got the following compiler error:
Error: Unexpected keyword 'new' in implementation file
If I deleted the new keyword, I got another error:
Error: Successive arguments should be separated by spaces or tupled, and arguments involving function or method applications should be parenthesized
The "new" keyword are totally different in C# and F#.
Please show me how to do the same job in F#.
Thanks,
In C# string is the shortcut to System.String class. However, in F# string is a function which has obj as its input and returns a string which is overriden in obj.ToString():
let s = string('*', 3);; // tuple to string
// val s : string = "(*, 3)"
What you really want is creating a string by repeating '*' three times:
let s = new String('*', 3)
// val a : String = "***"
To be clear, from ... in ... select ... is C# LINQ syntax which is invalid in F#. Therefore, using computation expression instead:
let seqNum = seq {1..5}
let seqString = seq { for n in seqNum -> new String('*', n) }
To get some ideas of creating/using computation expression for Reactive Extension, take a look at the question and its answers at How do I change the Rx Builder implementation to fix the stack overflow exception?
Instead of using the String constructor use the String.replicate method.
String.replicate n "*"
There is no direct equivalent for String(char, int) but String.replicate: int -> string -> string is roughly the equivalent with string instead of char
F# version for that code
[1 .. 5]
|> Seq.map (fun i -> String.replicate i "*")
Here you go:
open System
open System.IO
open System.Reactive
open System.Reactive.Linq
let seqString = Observable.Range(1,5).Select(fun x -> String.replicate x "*")
using (seqString.Subscribe (fun x -> printfn "%s" x))
(fun _ -> Console.ReadLine() ) |> ignore
EDIT: As Paul suggested below two last lines can be replaced by simple
seqString.Subscribe (printfn "%s") |> ignore
However, if we want to gracefully unsubscribe from our subscription, but get rid of using in lieu of newer use syntax we may replace last two lines by the following three
do
use subscription = seqString.Subscribe(printfn "%s")
Console.ReadLine() |> ignore