我今天刚刚开始学习F#并开始在http://www.tryfsharp.org/Learn/getting-started#data-structures
的F#教程中学习在上面的部分中,提供了三个代码片段来解释记录和选项类型:
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"
我以为我可以像这样应用printRating
printRating unratedEdition
但是我收到以下错误
stdin(63,13): error FS0001: This expression was expected to have type
FSI_0005.Book
but here has type
FSI_0009.Book
我有点担心我在这里做错了什么。我完全失踪的任何明显原因?
答案 0 :(得分:3)
很高兴你弄清楚如何解决问题并继续学习教程!
我认为在Try F#中自动加载和评估代码片段有点令人困惑。问题是您首先评估第一个片段,该片段定义了Book
和unratedEdition
。然后,您评估重新定义Book
的第二个片段 - 现在,对于F#interactive,这是隐藏前一个定义的不同的类型 - 以及printRating
这是一个函数致力于Book
的新版本。当你打电话:
printRating unratedEdition
您正在调用printRating
这是一个以旧 Book
类型的值为 new Book
的函数作为参数(因为unratedEdition
是从早期的交互中定义的;它不会自动更新为新的Book
类型,并且这两种类型不兼容)。
如果您逐一评估以下三个片段,则可以理解这一点:
// 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
请注意,编辑器会抱怨上面的代码无效,因为它定义了Book
两次,所以你真的只能在Try F#中轻松地解决这个问题,这会在加载时删除编辑器的内容一个新的片段
答案 1 :(得分:1)
我通过一次性运行上述所有代码解决了我自己的问题。即发布所有3个片段加上我的
printRating unratedEdition
一起进入REPL ,然后点击RUN。以前我使用的是“加载并运行”每个代码段。我想这肯定是REPL的一些问题,或者我对REPL如何工作的有限理解。
编辑** 在整个教程中,我发现自己多次遇到这个问题。因此,如果您有错误,并且不知道原因,请尝试将所有相关代码插入REPL,然后点击运行。这解决了我到目前为止遇到的每个问题。