Stubborn warning FS0193 on valid code
See original GitHub issueThe following code typechecks and runs without issue, but generates a spurious warning about a missing type parameter constraint, and there seems to be no obvious solution to satisfy the compiler. This is happening on Visual F# 3.1.2.
#!/usr/bin/env fsharpi
open System
type CShow = class
static member inline show (x : int) = sprintf "%d" x
static member inline show (x : string) = sprintf "\"%s\"" x
end
type Instance<'a, 'b, 'c when
(^a or ^b) : (static member show : ^b -> ^c)> = class
static member inline instance (b : ^b) =
((^a or ^b) : (static member show : ^b -> ^c) b)
end
type IShow = interface
abstract show : unit -> string
end
let inline Show arg = {
new IShow with
member __.show () = Instance<CShow, _, string>.instance arg }
let inline cout (x : string) = Console.WriteLine x
let inline show (x : #IShow) = x.show ()
let _ =
[Show 1; Show "arsdf"]
|> List.iter (show >> cout)
The warning is: Blarg.fsx(13,5): warning FS0193: A type parameter is missing a constraint 'when ( ^a or ^b) : (static member show : ^b -> 'c)'
(the line with the static member invocation).
Issue Analytics
- State:
- Created 8 years ago
- Comments:13 (12 by maintainers)
Top Results From Across the Web
F# 4.5.0.0: error FS0193: This expression is a function ...
I'm adapting a class from C# to F#, in the code I have a method that throws an exception and this method needs...
Read more >Untitled
02336 code, Belas donas flores, Ou spring game 2014 tv channel, Ct70 lifan 140, ... Hillyard spokane boundaries, Gironda chest press, True crime...
Read more >Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start FreeTop Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Top GitHub Comments
@dsyme, seeing the other “generic type pretty printing” related issues getting coallesced with this older one (makes sense), and on the topic of the pretty printing approach becoming easier to use to contributors, I was wondering if by gleaning more intuition about how this code evolved and ideally would be supposed to work, you may be in a place to improve that infrastructure with stronger invariants / making it easier for contributors to leverage?
I remember the pretty printing with those concerns was a bit of a sticking point I had to grok based on your input, when doing the overload resolution failure error message work, I didn’t feel super confident using the right APIs and in my refactorings to enable what I ended up using in the implementation.
It would be great if someone had a clear idea on how we could architecturally solve this (consuming the code being correct 99% of time just by construction, and refactoring/extending the infrastructure feeling less “what am I going to break” inducing, at least for casual contributors).
It could be there is just a missing call to “convert unnamed identifier to generic identifier for pretty printing” in many/some places, but just fixing it with current infrastructure may not address the potential for the issue to show when adding code, if there is already some knowledge about feasibility of addressing the later, it peaks my curiosity that some of this knowledge would write itself in this issue until a plan is put by the community to address it in the code.
I don’t want to distract anyone on an at-worst irritating bug, but I have a funny reproduction in F# 5.0 (in .NET Standard 2.0) that might shed some light on this strange behavior.
The following simple example raises a warning like the ones above:
The specific warning:
A type parameter is missing a constraint 'when ( ^T or ^?769536) : (static member ( + ) : ^T * ^?769536 -> ^T)'
(the random number usually indicates to me that the compiler is being fussy for some reason)However, this works without any warnings:
IntelliSense shows that F# is interpolating the types correctly. So for some reason F# doesn’t like the type annotations in this specific case. Funnily, I have this hideous type defined later which works flawlessly:
So this style of chaining together static member constraints can work really well at creating robust polymorphic code. It’s just a head scratcher when the compiler complains about it in seemingly arbitrary places.