You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

  1. Incorrect bind implementation
    Your bind function was passing a wrapped Success x (a Result<'a>) to the transformation function f, but functions like isPositive expect a raw value (e.g., int) instead of a wrapped result. This caused a fundamental type mismatch.

  2. Wrong parameter order for bind
    You tried to partially apply bind isPositive to create a reusable function, but your original bind took the Result first and the function second—this made partial application return an unexpected type. F# conventions typically place the function first for easier partial application.

  3. 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.

  4. Reversed >>= operator logic
    Your operator definition flipped the order of the Result and function, breaking the monadic chain flow.

  5. Missing parentheses for ToString()
    mys.ToString is 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 bind properly unwraps the Result and passes the raw value to your transformation functions.
  • The >>= operator follows standard monadic convention, making the chain stringToInt s >>= isPositive >>= toString read 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" returns Success "9", invalid inputs (e.g., "abc" or "-5") return Failure.

内容的提问来源于stack exchange,提问作者Wally

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.11 09:31:17