I am new to F#, so forgive me if this question seems silly, or if it is duplicated. If it is a duplicate, I couldn't find the answer.
The closest articles I could find are here and here. The second link has a hint to an answer, but isn't exact.
My question is this: How would I declare a variable to be specifically one type?
For example, the statement let i = 1 is basically just saying i is an integer, but only because it is set to one. So you could also say let i = "cake" and i would be a string.
Can you say something like let int i = 1? I noticed in the second link that you can kind of "re-declare" a variable by doing something like <variable> : <type>, but how would you do this in the initial declaration in F#?
To close this question officially, via Jeff Mercado's comment:
let i: int = 1
So let <variable name>:<variable type> = <value>
If you do something like let i : float = 1 it will instead throw a syntax error and require you to put in something like let i : float = 1.00.
Related
I am working though this example of the Open XML SDK using F#
When I get to this line of code
sheet.Id = spreadsheetDocument.WorkbookPart.GetIdOfPart(worksheetPart)
I am getting a null ref exception when I implement it like this:
sheet.Id.Value <- document.WorkbookPart.GetIdOfPart(worksheetPart)
Is there another way to assign that value? System.Reflection?
I got it working like this:
let sheet = new Sheet
(
Id = new StringValue(spreadsheetDocument.WorkbookPart.GetIdOfPart(worksheetPart)),
SheetId = UInt32Value.FromUInt32(1u),
Name = new StringValue("mySheet")
)
If You want to take a look to the entire sample translated to F#, it's here.
To clarify what's going on, the problem is that sheet.Id is initially null. If we look at the following:
sheet.Id.Value <- document.WorkbookPart.GetIdOfPart(worksheetPart)
The code tries to access the sheet.Id and invoke its Value property setter, but the Id itself is null. The answer posted by Grzegorz sets the value of the whole Id property - it's done in a construtor syntax, but it's equivalent to writing the following:
sheet.Id <- new StringValue(spreadsheetDocument.WorkbookPart.GetIdOfPart(worksheetPart))
This sets the whole Id property to a new StringValue instance.
I am developing an iOs application with Swift and a total novice in application development. I use SwiftDate external library to deal with dates. SwiftDate is installed with CocoaPods and it is imported correctly in the project.
But I can't figure out why I get this error when I compile my project :
Extraneous argument label 'localeID' in call
For this code :
let now = NSDate()
let nowHere = now.toString() // E.g. 21-Dec-15 12:00 CET
let nowInFrench = now.inRegion(localeID: "fr_FR").toString()
I understand that's because the parameters are not formatted correctly, but this an exemple from the documentation so I am a little bit lost for this problem.
Thank's.
As Oliver mentioned, the first problem is the argument label in
let nowInFrench = now.inRegion(localeID: "fr_FR").toString()
to fix your
Extraneous argument label 'localeID' in call
error write it like this
let nowInFrench = now.inRegion("fr_FR").toString()
then you will come to the
Cannot convert value of type string to expect argument type Region
Error. This means you cannot simply give the function inRegion a String object. It wants a Region objects. The documentation says use create a region
let paris = DateRegion(timeZoneID: "CEST", localeID: "fr_FR")
let nowInFrench = now.inRegion(paris).toString()
The error is being flagged up because for the first argument in a function the label doesn't need to be written, only the ones after that.
If you just write:
let nowInFrench = now.inRegion("fr_FR").toString()
The error should go away.
I don't know why the example is written that way, maybe just for clarity.
Edit: having looked at the documentation I do think they have just included the labels to be clear as to what type they are using as an argument.
Hi all real newbie question here.
I have an array like this:
var daysInMonth = Array<([MyCustomClass], NSDate)>()
How can I append an element to this?
I am having difficulty doing so. Trying something like this:
daysInMonth.append([MyCustomClass](), someDate)
or
daysInMonth.append( ([MyCustomClass](), someDate) )
will not work (i'd like to add an empty array initial above of type MyCustomClass, as well as some date that I have) but these are failing (error missing parameter #2 in call)
Any thoughts on what I am lacking in my syntax?
Thanks!
It looks like a swift bug to me. The swift compiler cannot correctly parse the "( (...) )" as passing in a tuple to a function.
If I break the append operation into two statements, it works.
var daysInMonth = Array<([MyCustomClass], NSDate)>()
let data = ([MyCustomClass()], NSDate()) // assuming MyCustomClass init() taks no parameter
daysInMonth.append(data)
note: It was [MyCustomClass]() in your question, which is incorrect.
Try declaring your array using the newer Array syntax instead:
var daysInMonth = [([MyCustomClass], NSDate)]()
Then, this works:
daysInMonth.append(([MyCustomClass](), NSDate()))
I am new to F#, looking at it as an alternative to Matlab.
In reference to this question, how can I create an empty Serie and an empty Frame.
If I did not just miss it, why an empty Serie or Frame has not been designed in the library,
something like list.empty ?
Adding Frame.empty and Series.empty is a great suggestion. I think these should be in the library and I'm adding an issue to GitHub to make sure they get added.
In the meantime, you should be able to use something like this:
let empty : Series<int, float> = series []
let empty : Frame<int, string> = frame []
Note that I had to add type annotations - from my code snippet, the compiler cannot figure out what is the type of keys and values, so I had to explicitly specify that (but if you use the values as arguments to other functions, then this should not be needed).
The second line does not actually work in the current version, because of a bug (oops!) so you can use Frame.ofRows instead, which works fine:
let frame : Frame<int, string> = Frame.ofRows []
EDIT: The bug is now fixed in version 0.9.11-beta
I just started studying F# today and have begun working my way through the F# tutorials at http://www.tryfsharp.org/Learn/getting-started#data-structures
In the section above three snippets of code are provided to explain records and option types:
type Book =
{ Name: string;
AuthorName: string;
Rating: int option;
ISBN: string }
let unratedEdition =
{ Name = "Expert F#";
AuthorName = "Don Syme, Adam Granicz, Antonio Cisternino";
Rating = None;
ISBN = "1590598504" }
let printRating book =
match book.Rating with
| Some rating ->
printfn "I give this book %d star(s) out of 5!" rating
| None -> printfn "I didn't review this book"
I thought that I would be able to apply the printRating like so
printRating unratedEdition
but I get the following error
stdin(63,13): error FS0001: This expression was expected to have type
FSI_0005.Book
but here has type
FSI_0009.Book
I'm kinda stuck as to what I am doing wrong here. Any obvious reason that I am totally missing?
Glad that you figured out how to solve the problem and continue with the tutorials!
I think the automatic loading and evaluation of code snippets in Try F# is a bit confusing. The problem is that you first evaluate first snippet, which defined Book and unratedEdition. Then, you evaluate second snippet which re-defines Book - now, to F# interactive, this is a different type hiding the previous definition - together with printRating which is a function working on the new version of Book. When you call:
printRating unratedEdition
You are calling printRating which is a function that takes the new Book with a value of the old Book type as an argument (because unratedEdition is defined from an earlier interaction; it does not automatically get updated to the new Book type and the two types are not compatible).
You can understand this if you evaluate the following three snippets one by one:
// Snippet #1: Define first version of the 'Book' type and a value of
// this type named 'unratedEdition'
type Book =
{ Name: string; AuthorName: string; Rating: int option; ISBN: string }
let unratedEdition =
{ Name = "Expert F#"; Rating = None; ISBN = "1590598504";
AuthorName = "Don Syme, Adam Granicz, Antonio Cisternino"; }
// Snippet #2: Now, we re-define the 'Book' type (we could also add/remove
// fields to make it actually different, but even without that, this still
// defines a new type hiding the original one). We also define a function that
// operates on the new 'Book' type
type Book =
{ Name: string; AuthorName: string; Rating: int option; ISBN: string }
let printRating book =
match book.Rating with
| Some rating ->
printfn "I give this book %d star(s) out of 5!" rating
| None -> printfn "I didn't review this book"
// Snippet #3: This will not work, because we are calling function taking new
// 'Book' with old 'Book' as an argument. To make this work, you need to evaluate
// one (or the other) definition of Book, then evaluate 'unratedEdition' and then
// 'printRating' (so that the value and function operate on the same 'Book' type)
printRating unratedEdition
Note that the editor will complain that the above code is not valid, because it defines Book twice, so you can really only get this problem (easily) in Try F# which erases the content of the editor when loading a new snippet
Well I solved my own problem by running all the above code in one shot. i.e. Posting all 3 snippets plus my
printRating unratedEdition
into the REPL together and then hitting RUN. Previously I was using the "load and run" for each individual snippet. I guess it must be some issue with the REPL, or my limited understanding of how a REPL works.
EDIT**
I found myself running into this problem a number of times throughout the tutorial. So, if you have an error, and don't know why, try inserting all the relevant code into the REPL, THEN hit run. This has solved every issue I have run into so far.