为什么我的Elmish.WPF示例NewWindow (XAML码和F#芯)会发出错误.
同一行发出警告..。
为什么我会收到这个错误和警告?
我要做的是将Elmish.WPF sample SingleCounter (XAML码和F#芯)和NewWindow (XAML码和F#芯)合并为Program.fs中的Model、bindings()和Msg部件,而不是App.fs (就像NewWindow示例中的那样)。
我的目标是使SimpleCounter能够打开NewWindow。
XAML代码将Func<Window2>传递给这里的F#代码..。
let main mainWindow (createWindow2: Func<#Window>)...I定义bindings为..。
let bindings = Platform.bindings createWindow_Window2下面是我前面提到的一个编译器错误(这也出现在"let bindings =.“开头的一行中)。)..。
let main mainWindow (createWindow_Window2: Func<#Window>) =
let logger =
LoggerConfiguration()
.MinimumLevel.Override("Elmish.WPF.Update", Events.LogEventLevel.Verbose)
.MinimumLevel.Override("Elmish.WPF.Bindings", Events.LogEventLevel.Verbose)
.MinimumLevel.Override("Elmish.WPF.Performance", Events.LogEventLevel.Verbose)
.WriteTo.Console()
.CreateLogger()
let createWindow_Window2 =
let window = createWindow_Window2.Invoke()
window.Owner <- mainWindow
window
let bindings = Platform.bindings createWindow_Window2
WpfProgram.mkProgramWithCmdMsg (fun _ -> m_init, []) update bindings toCmd
|> WpfProgram.withLogger (new SerilogLoggerFactory(logger))
|> WpfProgram.startElmishLoop mainWindowProgram.bindings的顶部定义为..。
let bindings (createWindow_Window2: unit -> #Window) () : Binding<Model, Msg> list = [
"Window_Window2_Show|> Binding.cmd Window_AboutProduct_Show
"Window_Window2" |> Binding.subModelWin(
Window_Window2.get >> WindowState.ofOption,
snd,
Window_Window2ct.mapInOutMsg,
Window_Window2_Module.Window_Window2.bindings,
createWindow_Window2,
isModal = true)
...bindings continue but are not relevant to this question.....。报告没有错误!
编译器似乎认为,当Platform.bindings被正确地键入为unit -> #Window__时,createWindow_Window2正在等待unit -> #Window。
您可以看到对Program.fs:main的调用是从App.xaml.cs正确调用的,其中一个lambda函数返回一个Window2,如下所示。
private void StartElmish(object sender, EventArgs e)
{
this.Activated -= StartElmish;
Program.main(MainWindow, () => new Window2());
}所以我的问题是,当我传递正确的类型时,为什么会得到这个不匹配的类型错误?
谢谢!
发布于 2022-07-08 15:02:14
非常感谢你:布莱恩·伯恩斯,本特·特兰贝格和托马斯·彼得里克,感谢你帮助我!
对专家来说,对我的问题的答案非常简单,但相对新手来说,只有在与NewWindow的工作NewWindow代码进行了细致的比较之后,才能给出答案。
为了便于比较,我把rfreytag/Elmish.WPF推到了NewWindow (XAML代码和F#芯)示例的一个版本,该示例编译并运行(请记住构建NewWindow示例)。
此版本的NewWindow (XAML码和F#芯)在编译时显示了我在…中报告的错误和警告。
The type 'unit -> 'a' is not compatible with the type 'Window'.
See also C:\Workspace\Elmish.WPF\src\Samples\AnotherNewWindow.Core\Program.fs(78,72)-(78,79)....and警告..。
This construct causes code to be less generic than indicated by its
type annotations. The type variable implied by the use of a '#', '_'
or other type annotation at or near
'C:\Workspace\Elmish.WPF\src\Samples\AnotherNewWindow.Core\Program.fs(78,72)-(78,79)'
has been constrained to be type 'unit -> 'a'.要查看精确的修复,您可以比较我的Elmish.WPF副本上的工作分支和断裂分支。那就是我忘记了()的定义,let createWindow_Window2 = .
let createWindow_Window2 =
let window = createWindow_Window2.Invoke()
window.Owner <- mainWindow
window..。返回函数() -> Window,而正确的..。
let createWindow_Window2 () =
let window = createWindow_Window2.Invoke()
window.Owner <- mainWindow
window..。返回所需的Window。
新手看着unit → ‘a,并不会立即将其识别为一个函数。当然,函数不是C# Window对象。
没有帮助我的错误信息不遵循F#形式的.
expecting a <type sought by context>
but was given a <passed in type>...which已经熟悉了使用F#编译器的过程。
不知道为什么这个消息会偏离这个模式。也许有人能解释一下?
该警告正在提醒特定较少的#Window (参见#“灵活类型”定义),可能在运行时与unit → ‘a函数发生冲突。
和往常一样,学习一个新的框架意味着学习编译器和链接器消息。
发布于 2022-07-01 22:55:56
我认为您代码中的一个问题是,名称createWindow_Window2既用作main参数的名称,又用作差异类型函数中的局部变量。另一个问题是,在一个地方,您尝试使用委托类型Func<#Window>,而在另一个地方,您有一个普通的F#函数Window -> unit。
我的建议是在任何地方使用Window -> unit,避免变量阴影:
let main mainWindow (createWindow_Window2:Window -> unit) = (* Changed type here *)
let logger = (* omitted *)
let createWindowWithOwner () =
(* Renamed and added '()' so that it is a function *)
let window = createWindow_Window2 () (* Just function call *)
window.Owner <- mainWindow
window
let bindings =
Platform.bindings createWindowWithOwner (* Pass the right function here *)
(* omitted *)https://stackoverflow.com/questions/72821585
复制相似问题