问题
I have written such a function in F#:
let TwistBasket (reverse: bool, quarters: int, overTwist: int byref) =
overTwist <- 50
WaitForBasketReady()
waitBasket.Reset()
let move = 135*quarters - 25 + overTwist
let speed =
match reverse with
| true -> -75y
| false -> 75y
let waitHandle = motorBasket.SpeedProfile(speed, 15u, uint32 move, 10u, true)
Task.Factory.StartNew(fun () ->
waitHandle.WaitOne()
if (overTwist <> 0) then
motorBasket.SpeedProfile(sbyte -speed, 0u, uint32 overTwist, 0u, true).WaitOne()
waitBasket.Set()
On this if statement ;
if (overTwist <> 0) then
motorBasket.SpeedProfile(sbyte -speed, 0u, uint32 overTwist, 0u, true).WaitOne()
I get the error: This expression was expected to have type unit but here has type bool.
Actually motorBasket.SpeedProfile().WaitOne()
returns boolean statement. I need it.
Because I'm trying to convert this if else statement in C#:
Task.Factory.StartNew(() =>
{
waitHandle.WaitOne();
if (overTwist != 0)
{
motorBasket.SpeedProfile((sbyte) -speed, 0, (uint) overTwist, 0, true).WaitOne();
}
waitBasket.Set();
});
How can I fix my error?
回答1:
By looking at the C# version, it does nothing with the result. So in F# I would call ignore
which will eat the result:
if (overTwist <> 0) then
motorBasket.SpeedProfile(sbyte -speed, 0u, uint32 overTwist, 0u, true).WaitOne() |> ignore
F# is more strict than C# in these cases, if your if .. then has no else branch it result should be unit, which makes perfect sense.
You can also create an else branch with a (dummy) boolean value and let-bind it to a (dummy) value, but in this particular case what's the point if you're really not going to use that value? What you're really doing is creating a side effect and ignoring the result, F# drives you to make it more explicit in your code.
回答2:
In F# if/else
expressions should have the same type. If you are using if
expression without else
branch then F# compiler consider that implicitly else
branch has type unit
hence the error.
You could change your code to explicitly use else branch:
if (overTwist <> 0) then
motorBasket.SpeedProfile(sbyte -speed, 0u, uint32 overTwist, 0u, true).WaitOne()
else
... // Put here expression of the same type as if (I assume it's bool)
Or you can use ignore
function in if branch as Gustavo mentioned.
来源:https://stackoverflow.com/questions/27735519/f-compiler-error-this-expression-was-expected-to-have-type-unit-but-here-has-t