Reputation: 71
I love computation expressions, but I make simple mistakes like forgetting the return keyword or the ! on expressions like let! and return!, or I simply forget to write the do!. This happens much with state monads where I tend to forget about the state and just focus on the monadic operators I have defined.
I sometimes make sure my monadic operators return a type that is "of monad type" instead of an "anonymous" function. This helps to track my forgetful typing, yet is not really ideal. Anybody have better tricks?
Upvotes: 2
Views: 213
Reputation: 55195
Given a typical monad, your code shouldn't compile if you're missing a !
after a keyword because the types won't work out. For example:
let sum = async {
let x = async { return 1 }
let y = async { return 2 }
return x + y
}
This won't compile because you're attempting to add two Async<int>
s, but it will compile if you change the let
s to let!
s.
Similarly, to identify missing return
s, just look out for compiler warning messages and odd monadic types:
let sum = async {
let! x = async { return 1 }
let! y = async { return 2 }
x + y // warning FS0020
}
In this case, sum
is an Async<unit>
, which should be apparent when you try to use it elsewhere in your code. Alternatively, you can use a type annotation to catch this problem immediately:
let sum : Async<int> = async { // error FS0001: type mismatch
let! x = async { return 1 }
let! y = async { return 2 }
x + y // warning FS0020
}
Upvotes: 3