Replies: 1 comment 2 replies
-
Yeah, I was speculating in my comment on the issue based on the names of your types. My main point from #18569 (comment) about type inference flowing from left to right in this situation still holds, though. That is, the compiler already does give a better error message if you pipe let checkLine (line : GamePiece<TickTackToePiece> option list) =
line.Length > 0 && line |> List.forall (fun piece -> piece <> Nothing && piece = line.Head) line.Length > 0 && line |> List.forall (fun piece -> piece <> Nothing && piece = line.Head)
------------------------------------------------------------------^^^^^^^
stdin(40,67): error FS0001: This expression was expected to have type
'GamePiece<TickTackToePiece> option'
but here has type
'Piece<'a>' While it would be nice if the compiler could tell you to consider changing application order to improve type inference in such a scenario, I am not sure that it would be easy to make it do that in a performant way. (It would basically need to try typechecking from both directions to know for sure, which sounds expensive.) Separately, here is another way that you could write your let checkLine (line : GamePiece<TickTackToePiece> option list) =
match line with
// Empty list.
| []
// First element is None.
| None :: _
// First element is Nothing.
| Some { Piece = Nothing } :: _ -> false
// We only need to check the rest of the list at all
// if the first piece is Some and Piece is a GamePiece.
| Some ({ Piece = GamePiece _ } as gamePiece) :: tail -> tail |> List.forall (Option.contains gamePiece) There are additional ways you could adjust your model to improve things further, but that is a separate discussion :) |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
-
I originally created this as an issue but got the suggestion to create it as a discussion instead:
#18569
I believe we could have clearer type error messages by prioritizing declared types in type assumptions.
I think this is best explained by showing you why I ended up making this suggestion. I was fixing some code after a bunch of changes in a board game project. I had this error to fix(picture included to show where the error showed up)
I deduced for myself, maybe I'm wrong, that because I'm making the boolean check of "piece <> Nothing" where Nothing is a Piece<'T> instead of a GamePiece<'T>. So the error is sorta assumed in reverse even though I have specified the type on the parameter line.
Here is the code if somebody would like to copy it:
Here is the code for my types, I did not use inheritance as suggested in the issue:
And for further context here is the fixed version of checkLine
I hope this makes sense :)
Beta Was this translation helpful? Give feedback.
All reactions