我一直试图了解F#的各个部分(我来自更多的C#背景),解析器对我感兴趣,所以我跳过这篇关于F#解析器组合器的博文:
http://santialbo.com/blog/2013/03/24/introduction-to-parser-combinators
这里有一个样本:
/// If the stream starts with c, returns Success, otherwise returns Failure
let CharParser (c: char) : Parser<char> =
let p stream =
match stream with
| x::xs when x = c -> Success(x, xs)
| _ -> Failure
in p //what does this mean?
然而,让我对此代码感到困惑的一件事是in p
语句。我查找了MSDN文档中的in
关键字:
http://msdn.microsoft.com/en-us/library/dd233249.aspx
我也发现了之前的问题:
这些似乎都没有相同的用法。唯一合适的是这是一个流水线构造。
答案 0 :(得分:8)
let x = ... in expr
允许您声明某个变量x
的绑定,然后可以在expr中使用。
在这种情况下,p
是一个函数,它接受一个参数stream
,然后根据匹配的结果返回Success
或Failure
,这个函数是由CharParser
函数返回。
F#light syntax会自动嵌套let .. in
个绑定,例如
let x = 1
let y = x + 2
y * z
与
相同let x = 1 in
let y = x + 2 in
y * z
因此,此处不需要in
,函数可以简单地写为
let CharParser (c: char) : Parser<char> =
let p stream =
match stream with
| x::xs when x = c -> Success(x, xs)
| _ -> Failure
p
答案 1 :(得分:8)
Lee的回答解释了这个问题。在F#中,in
关键字是早期函数语言的遗产,它启发了F#并且需要它 - 即来自ML和OCaml。
可能值得补充的是,在F#中只有一种情况,您仍然需要in
- 也就是说,当您想要在单行上编写let
后跟表达式时。例如:
let a = 10
if (let x = a * a in x = 100) then printfn "Ok"
这是一种有点时髦的编码风格,我通常不会使用它,但如果你想这样写,你需要in
。您可以随时将其拆分为多行:
let a = 10
if ( let x = a * a
x = 100 ) then printfn "Ok"