2017-07-17 45 views
2

我无法对此错误给出解释(VS 2017中的F#4.1)。F#在继承的构造函数参数列表中分配继承的属性值

公共代码:

open Eto.Forms 

type MyCommand() as this = 
    inherit Eto.Forms.Command() 
    do 
     this.MenuText <- "C&lick Me, Command" 
     this.ToolBarText <- "Click Me" 
     this.ToolTip <- "This shows a dialog for no reason" 
     this.Shortcut <- Application.Instance.CommonModifier ||| Keys.M 

下面的声明不是由F#编辑接受;在菜单初始化检测到的错误消息“命名的参数必须在所有其它参数之后出现”:

type MyForm1() = 
    inherit Eto.Forms.Form(
     Title = "Eto Tests" 
     , ClientSize = Eto.Drawing.Size(600, 400) 
     , Menu = seq {yield new MyCommand()} |> Seq.fold (fun (mb:MenuBar) c -> mb.Items.Add(c) |> ignore; mb) (new MenuBar()) 
    ) 

下面的声明没有工作,而不是错误:事先

type MyForm1() = 
    inherit Eto.Forms.Form(
     Title = "Eto Tests" 
     , ClientSize = Eto.Drawing.Size(600, 400) 
     , Menu = let m = seq {yield new MyCommand()} |> Seq.fold (fun (mb:MenuBar) c -> mb.Items.Add(c) |> ignore; mb) (new MenuBar()) in m 
    ) 

感谢。

+3

看起来像''let m = ... in ...''构造就像这里的一对圆括号一样工作。尝试在代码中使用“Menu =(seq {yield ...(new MenuBar()))”。 – dumetrulo

回答

4

它看起来像参数值中的某些字符残留解析器,它解析整个东西作为比较(即x = y),并且因为这是一个布尔值,它假定它必须是一个未命名参数的值,因此错误。

我找不到在F#规范任何提到这一点,但我的实验迄今已经发现,得罪字符的列表包括(但不限于)<>$&。加号+和花括号{ }不在列表中。

type T = T with static member M(x: int, y: bool, z: int seq) =() 
let inline ($) a b = a + b 

T.M(
    y = true, z = [], 
    x = 5 $ 4 // Fails 
) 

T.M(
    y = true, z = [], 
    x = 5 + 4 // Works 
) 

T.M(
    y = true, x = 5, 
    z = seq { yield 5 } // Works 
) 

T.M(
    y = true, z = [], 
    x = seq { yield 5 } |> Seq.head // Fails due to the `>` symbol in the pipe 
) 


T.M(
    x = 5, z = [], 
    y = 4 < 3 // Fails 
) 

T.M(
    x = 5, z = [], 
    y = true & false // Fails 
) 

幸运的是,有一种解决方法:将整个值放在一对圆括号中。这有助于解析器正确地确定值的位置。