F#实现Result Monad遭遇FS0001编译错误,求代码修正
Let's break down what's going wrong with your code and fix it step by step:
Key Issues in Your Original Code
Incorrect
bindimplementation
Yourbindfunction was passing a wrappedSuccess x(aResult<'a>) to the transformation functionf, but functions likeisPositiveexpect a raw value (e.g.,int) instead of a wrapped result. This caused a fundamental type mismatch.Wrong parameter order for
bind
You tried to partially applybind isPositiveto create a reusable function, but your originalbindtook theResultfirst and the function second—this made partial application return an unexpected type. F# conventions typically place the function first for easier partial application.Redundant and incorrectly typed
bindIsPositive/bindToString
These variables had wrong type annotations and were unnecessary. The>>=operator can directly use your transformation functions (isPositive,toString) without pre-binding.Reversed
>>=operator logic
Your operator definition flipped the order of theResultand function, breaking the monadic chain flow.Missing parentheses for
ToString()mys.ToStringis a method reference, not an executed method—you need parentheses to call it and get the string output.
Fixed Code
open System type Result<'TSuccess> = | Success of 'TSuccess | Failure // Corrected bind: takes transformation function first, then Result // Passes raw value to the function on Success let bind (f: 'a -> Result<'b>) (x: Result<'a>) = match x with | Success value -> f value | Failure -> Failure let stringToInt (s:string) = try let result = s |> int Success result with |_-> Failure let isPositive (i:int) = if i > 0 then Success i else Failure let toString (i:int) = try let result = i |> string Success result with |_ -> Failure // Standard monadic bind operator: x >>= f means "run x, then apply f to its result" let (>>=) x f = bind f x // Simplified chain: use transformation functions directly with >>= let strintToIntIsPositiveIntToString s = stringToInt s >>= isPositive >>= toString [<EntryPoint>] let main argv = let mys = strintToIntIsPositiveIntToString "9" Console.WriteLine(mys.ToString()) // Fixed method call with parentheses 0 // return an integer exit code
How This Works
- The corrected
bindproperly unwraps theResultand passes the raw value to your transformation functions. - The
>>=operator follows standard monadic convention, making the chainstringToInt s >>= isPositive >>= toStringread like a sequential pipeline: convert the string to an int, check if it's positive, then convert back to a string. - Testing with valid input like
"9"returnsSuccess "9", invalid inputs (e.g.,"abc"or"-5") returnFailure.
内容的提问来源于stack exchange,提问作者Wally

