F# - The type int is not compatible with type unit

2019-06-17 08:04发布

问题:

Quite new to functional languages, but I'm maintaining someone else's code with a lot of F#. Can anyone offer some insight into this?

        let mtvCap = Rendering.MTViewerCapture(mtViewer)
        mtvCap.GetCapture()
        mtvCap.ToWpfImage()
        grid.Children.Add(mtvCap.ImageElement)

MTViewer.ImageViewer is of type System.Windows.Controls.Image, and grid is System.Windows.Controls.Grid.

Again, error is: The type int is not compatible with type unit

回答1:

F# does not allow for you to silently ignore return values. The type unit is F#'s version of void. So the error is saying essentially

I expected the statement to have no return but instead it returns an int value

Or the opposite. I tend to incorrectly read this error message.

What's likely happening is one of the following

  1. The method in question is expecting an int return value but the method Add returns void hence F# is just asking for a return value
  2. The method in question is typed as unit but Add is returning an int and F# needs you to ignore the value.
  3. The GetCapture or ToWpfImage return values that need to be explicitly handled.

For the last 2 cases you can fix this by passing the value to the ignore function

mtvCap.GetCapture() |> ignore
mtvCap.ToWpfImage() |> ignore
grid.Children.Add(mtvCap.ImageElement) |> ignore

After digging around a bit I believe #2 is the issue because UIElementCollection.Add returns an int value. Try modifying the final line to look like this

grid.Children.Add(mtvCap.ImageElement) |> ignore


回答2:

I know remarkably little about F#, but as I recall, "unit" is their way of saying "void", so I'm gonna guess that you are trying to assign the "return value" of a function that doesn't have one, to a varaible. That would make the most likely candidate, this line:

let mtvCap = Rendering.MTViewerCapture(mtViewer)