帮助开始使用TryFSharp“记录和选项类型”教程

时间:2013-05-27 09:27:35

标签: f#

我今天刚刚开始学习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 

我有点担心我在这里做错了什么。我完全失踪的任何明显原因?

2 个答案:

答案 0 :(得分:3)

很高兴你弄清楚如何解决问题并继续学习教程!

我认为在Try F#中自动加载和评估代码片段有点令人困惑。问题是您首先评估第一个片段,该片段定义了BookunratedEdition。然后,您评估重新定义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,然后点击运行。这解决了我到目前为止遇到的每个问题。