[英]F# can't understand the delimitation my multiple argument values have. Why?
我实际上正面临着F#编译器潜在的奇怪问题。 以下代码给了我一个错误,我不明白为什么:
yield Animal(
AnimalType(animal.AnimalType.Value),
error-->if Option.isSome animal.AnimalSubType then Some(AnimalSubType(animal.AnimalSubType.Value)) else None,
AnimalSpecificSubType(animal.AnimalSpecificSubType.Value)
)
编译器抱怨Animal应该接受3个参数,但实际上只接受2个。我想它没有意识到if参数在行的结尾(以逗号结尾)。 我可以通过在令人讨厌的行周围添加()来使代码运行:
yield Animal(
AnimalType(animal.AnimalType.Value),
--> OK (if Option.isSome animal.AnimalSubType then Some(AnimalSubType(animal.AnimalSubType.Value)) else None),
AnimalSpecificSubType(animal.AnimalSpecificSubType.Value)
)
但我想了解这个问题。 为什么这可以解决问题,例如,不能解决?
yield Animal(
AnimalType(amimal.AnimalType.Value),
error-->if (Option.isSome animal.AnimalSubType) then (Some(AnimalSubType(animal.AnimalSubType.Value))) else (None),
AnimalSpecificSubType(animal.AnimalSpecificSubType.Value)
)
我没有看过F#的语法,但是我猜想每当F#看到if
子句时,它将期望else
子句,并可能后面跟随else
子句。 我猜想,只要我小心else
子句,一切都会好起来的。
怎么了
编译器将错误行末尾的逗号解释为else
分支返回的元组的一部分,即
yield Animal(
a,
if c then Some(b) else None,
d
)
解析为:
yield Animal(
a,
if c then Some(b) else ((None, ...? )
d
)
这就是您的第一个修订而不是第二个修订起作用的原因,因为在第二个修订中添加方括号只是包裹了幻影元组的第一个元素,而不是元组本身,即:
yield Animal(
a,
if c then Some(b) else (None),
d
)
解析为:
yield Animal(
a,
if c then Some(b) else ((None), ...? )
d
)
问题与如何在F#中创建元组有关:
> let test (a,b,c) = "Test"
> test(1, if true then Some 1 else None,1);;
test(1, if true then Some 1 else None,1);;
-----^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error FS0001: Type mismatch. Expecting a
'a * 'b * 'c
but given a
'a * 'b
The tuples have differing lengths of 3 and 2
这清楚地表明编译器认为test
正在采用两个参数,但是编译器认为这两个参数是什么? 由于这种类型的函数实际上只是将单个参数作为元组的函数,因此我们可以像下面这样来解构该行代码:
> 1, if true then Some 1 else None,1;;
1, if true then Some 1 else None,1;;
----------------------------^^^^^^
stdin(19,29): error FS0001: This expression was expected to have type
int option
but here has type
'a * 'b
因此,您可以看到编译器正在将None,1
视为if
表达式中else
的表达式,这就是为什么编译器需要int option
。 为防止这种情况,您需要向编译器指示if
表达式的开始和结束位置。 实现此目的的最简单方法是像这样简单地加上括号:
> 1,(if true then Some 1 else None),1;;
val it : int * int option * int = (1, Some 1, 1)
现在我们得到了预期的元组。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.