Elmish.WPF type conflict: unit -> Model expected where Model provided? - f#

My Elmish.WPF app combines the Elmish.WPF Sample projects ‘NewWindow’ + ‘NewWindow.Core’ which I am adding to a copy of ‘FileDialogsCmdMsg’ + ‘FileDialogsCmdMsg.Core’.
FileDialogsCmdMsg is the basis of this effort and provides the background processing features to which I am adding the ‘NewWindow’ popup window features.
I am stuck on two (2) type-conflicts when WpfProgram.mkProgramWithCmdMsg is called...
...errors on update and bindings calls.
The compiler reports that line has the following errors (see red underlines above)...
...saying that WpfProgram.mkProgramWithCmdMsg expects a unit -> Model but was given a Model where update and bindings are called in the larger type specification.
But here is the type information for the calling function, WpfProgram.mkProgramWithCmdMsg accepting these parameters…
... sorry that is so large.
As you can see, both ‘update’ and ‘bindings’ are producing the Model parameter types expected by WpfProgram.mdProgramWithCmdMsg. And yet we have a unit->Model expected where a Model has been provided type-conflict; why?
Here is more detail on the update type-conflict…
... see how here how here it is claimed a unit->Model is expected when previously you see that update is supposed to expect a Model? Why?
You see the same problem in this detail on the type-conflict with ‘bindings’...
..again showing unit-Model' expected when the correct Model` type parameter is passed.
Here the type information where update is defined…
...and here is the bindings type info…
QUESTION: Why is a "unit->Model expected error reported when the receiving function, WpfProgram.mkProgramWithCmdMsg, and both parameters, update and bindings both respectively provide Model parameters?
Please ask if more detail is needed to get to the bottom of this.
Thanks for your help!

I suspect the problem is with your init function, which (I'm guessing) is a function of type unit -> Model. If this is true, the lambda fun _ -> init, [] binds the concrete type unit -> Model to the 'model type variable. As result, update and bindings also expect the same concrete type, leading to the error message you're seeing.
If I'm correct, you have two choices:
Change init so it is a value of type Model, rather than a function.
Change init so it also returns an empty message list, and then pass init directly to mkProgramWithCmdMsg, rather than passing a lambda.
Note that when you hover over mkProgramWithCmdMsg, the compiler shows you that 'model is indeed bound to unit -> Model, presumably due to the init type mismatch:

Related

Type name as identifier in F#

I just started to study F# and accidentally wrote this binding
let List = 1
Now when I try to obtain List methods such as 'filter' I get this error
error FS0039: The field, constructor or member 'filter' is not defined.
Of course using method with full type name like Microsoft.FSharp.Collections.List.filter is still working.
I'm wondering why it is possible to use type name as identifier in F# and how I can set back name List to type List from Microsoft.FSharp.Collections.
When I tried to reassign like this
type List = Microsoft.FSharp.Collections.List<'T>
I get
Error FS0039: The type parameter 'T is not defined.
Thank you!
In F# you can redefine almost everything and shadow existing definitions. This applies to both types (well actually types have a different behavior regarding shadowing, they shadow their values as you open the namespaces) and values but not interchangeably since values and type (and also modules) can somehow coexist at the same time in the scope. The compiler will do his best to find out which one is.
You are not forced to, but it's a common good practice in F# not to use let bindings in uppercase.
Regarding your second question, you are using a type parameter in the right side which doesn't exist in the left side of the assignment, it should be:
type List<'T> = Microsoft.FSharp.Collections.List<'T>
But notice that filter doesn't belong to the type. It's rather defined in the List module.
You should just rename your let binding from List to something sensible - as Gustavo mentioned, your definition is shadowing the core List module from F# and there is no way to use List to refer both to your integer and to the module. Shadowing core functions will make your code pretty confusing. It's also a good idea to use camelCase for let bindings, but that's a matter of taste.
If you insist on shadowing List, then you won't be able to call List.filter using List.filter. If you wanted something shorter, you could define module alias:
module FsList = Microsoft.FSharp.Collections.List
Note that your attempt to do something similar with List<'T> does not do the same thing, because functions such as filter are in a module named List rather than being static members of the type. With this, you can call filter using FsList.filter.

F# type inferrence issue

I have experienced the following problem while writing a test. Please find a picture bellow.
If I create validateGameExistance function in the unit test project then it works fine.
How could it be solved?
It is hard to give a definite answer (based just on the screenshot), but you can get this kind of error when some of the types involved in the type error are defined in multiple places (so, the type name would look the same, but they would actually be different types in different assemblies).
For example, if the Result<T> type is defined in multiple projects and the function you're calling returns one of them, but your annotation is referring to another one.

FSharp GetGenericArguments().[0].Name returns T instead of actual type name

I'm having an issue trying to reflect over a generic argument in F#. I want to pass two types to a function: the first is the type I want to find implemented in another type (which is the 2nd parameter).
When I do this in C# I get the desired results. However when I do it in F# I get Type.Name = "T" instead of "SomeType". I have put together a Gist that hopefully illustrates what I'm trying to do (it's just a linqpad sample to show what I'm trying to do) in both C# and F#: https://gist.github.com/johnbfair/11263203
Why is the result of .GetGenericArguments.[0].Name = "T" instead of "MySample2" (which is what C# outputs)?
Looks like I was making the mistake of using "typedefof<>" instead of "typeof<>". Updated the gist accordingly.
To expand on the above:
When calling the function "typeImplements" I was passing in typedefof>. Unbeknownst to me typedefof doesn't include the type of the generic ('T) when interrogating the enclosing type (in this case MySample2). So if you want to get the actual type of the generic you need to use typeof>. This is the blog post that explained the difference to me: http://phosphor-escence.blogspot.com/2013/05/difference-between-typeof-and-typedefof.html
Before:
typeImplements typedefof<MySample2> typedefof<MySample1<MySample2>> |> Dump
After: typeImplements typeof<MySample2> typeof<MySample1<MySample2>> |> Dump

Fully qualified name, unqualified name with import declaration resolve differently

This works
open System
let f = Action(fun () -> Unchecked.defaultof<_>)
But this
let f = System.Action(fun () -> Unchecked.defaultof<_>)
produces the compilation error
Multiple types exist called 'Action', taking different numbers of generic parameters. Provide a type instantiation to disambiguate the type resolution, e.g. 'Action<,,_,,,_,,,_>'.
I know I can fix it by adding a type parameter placeholder (System.Action<_>(...)), but any idea why they behave differently?
EDIT
Found this in the spec, section 14.1.9:
When a module or namespace declaration group F is opened, items are added to the name environment as follows:
Add the type to the TypeNames table. If the type has a CLI-mangled generic name such as List'1 then an entry is added under both List and List'1.
Is this behavior replicated for fully-qualified types (with omitted type parameters)? It doesn't appear so.
I agree with #James that this is related to the bug submitted on Connect, but I think it is a slightly different case. Anyway, I think this is not the intended behaviour. Could you report it to fsbugs at microsoft dot com?
Anyway - I did some debugging and here is what I found so far:
It seems that the compiler uses different code paths to resolve the name Action and the name System.Action. When resolving the other, it searches all loaded modules (i.e. assemblies) for a type named System.Action (see ResolveLongIndentAsModuleOrNamespaceThen function in the nameres.fs file of the open-source release).
This finds the two definitions of Action (one in mscorlib and another in System.Core). I think the issue comes from the fact that the name resolution simply iterates over the results - it finds the first one (from System.Core), which doesn't have a usable overload (because it ranges from Action<_,_,_,_,_> to a version with about 15 type parameters). After finding this type, it reports an error without even looking whether there is another type (in another assembly) that could be used.
If you don't reference system assemblies, then the F# compiler resolves the overload just fine. Running the compiler without parameters references the default assembly set, so this doesn't work:
fsc test.fs
but if I add the --noframework flag, then it compiles without issues:
fsc --noframework test.fs

Why does Delphi Prism complain about System type mismatches?

I encountered a strange compiler error in Delphi Prism 2010 that I am unable to resolve. The error is calling a method on an object defined in a third-party assembly that manipulates a specialized image format. The assembly itself was compiled against the .Net 2.0 Runtime.
Despite providing the correct list of parameters, I consistently get an error and series of warning messages indicating the parameter list is incorrect. The VS 2008 IDE also refuses to perform parameter completion, yet correctly shows the method prototype and allows the method to be added using Ctrl-Space. Below is an abbreviated version of the compiler errors to illustrate the problem:
Error 1 (PE19) There is no overloaded method "GetTempMapOfIRSensor" with these parameters
Warning 2 (PH2) Best matching "Image.GetTempMapOfIRSensor(var rectOnSensor: System.Drawing.Rectangle; out average: System.Double; out minTempArrayIndex: System.Int32; out maxTempArrayIndex: System.Int32; desiredTempUnits: Image.TEMP_UNIT): array of System.Double" doesn't match on parameter 1, parameter is "System.Drawing.Rectangle" should be "System.Drawing.Rectangle"
Warning 3 (PH2) Best matching "Image.GetTempMapOfIRSensor(var rectOnSensor: System.Drawing.Rectangle; out average: System.Double; out minTempArrayIndex: System.Int32; out maxTempArrayIndex: System.Int32; desiredTempUnits: Fluke.Thermography.TEMP_UNIT): array of System.Double" doesn't match on parameter 2, parameter is "System.Double" should be "System.Double"
....a list of similar warnings for each remaining parameter
The strange part is that the compiler complains about a type mismatch for each and every parameter, yet the error message shows the parameter type names are the same (e.g. parameter is "System.Double" should be "System.Double").
Any suggestions on how to troubleshoot and resolve this issue would be welcome. The class in question, other than this one method, seems to work fine in every other respect. I am also able to create a method on the local class with the same signature and call it without error.
Update:
Invoking the method using reflection and the same parameter list works properly. This is looking to be a compiler bug/limitation of some sort.
If this library has overloads for non-var/out & var or out parameters with the rest of the signature the same, turn off the option for implicit out/var parameters and add out & var in the places they're needed. That should fix, else a QC entry generally is fixed quite fast, if it's a bug.

Resources