什么是monadic错误?

问题描述:

我读到关于monadic错误作为返回值错误和异常的替代方法。有人可以解释和举例说明一个单一的错误如何在一个命令性的伪语言中工作(请不要使用功能性示例)。什么是monadic错误?

的基本思想:

  • 与输出成功的概念或失败,错误被编码成类型。
  • 此类型的值(或函数)可以组成另一个此类型的值。具有不同成功类型的值可以组成,但它们必须都具有相同的失败类型。
  • 一旦输出错误,执行的其余部分就会短路以传播错误。

这里是C#中的工作示例:


// A discrimated union that can be either an error of type TError, 
// or a successful result of type TResult. 
// IsError indicates which field has a valid value. 
class Throws<TError, TResult> 
{ 
    public bool IsError; 
    public TError Error; 
    public TResult Result; 

    // Make a new successful reslt of type TResult. 
    public static Throws<TError, TResult> Success(TResult result) 
    { 
     Throws<TError, TResult> t = new Throws<TError, TResult>(); 
     t.IsError = false; 
     t.Result = result; 
     return t; 
    } 

    // Make a new error of type TError. 
    public static Throws<TError, TResult> Fail(TError error) 
    { 
     Throws<TError, TResult> t = new Throws<TError, TResult>(); 
     t.IsError = true; 
     t.Error = error; 
     return t; 
    } 

    // Composition. 
    public Throws<TError, TResultB> Bind<TResultB>(
       Func<TResult, Throws<TError, TResultB>> f) 
    { 
     if (IsError) 
     { 
      // If this is an error, then we can short circuit the evaluation 
      return Throws<TError, TResultB>.Fail(Error); 
     } 

     // Otherwise, forward this result to the next computation. 
     return f(Result); 
    } 
} 

class Test 
{ 
    // num/demom 
    private static Throws<string, double> Div(double num, double denom) 
    { 
     if (denom == 0) 
      return Throws<string, double>.Fail("divide by zero"); 

     return Throws<string, double>.Success(num/denom); 
    } 

    // Have the user enter a double. 
    private static Throws<string, double> ReadDouble(string name) 
    { 
     Console.Write("{0}: ", name); 

     string input = Console.ReadLine(); 
     double result; 
     if (!double.TryParse(input, out result)) 
      return Throws<string, double>.Fail(string.Format("can't parse {0}", name)); 

     return Throws<string, double>.Success(result); 
    } 

    // Read two doubles and divide them to produce the result. 
    private static Throws<string, double> Interact() 
    { 
     return ReadDouble("numerator").Bind(num => 
       ReadDouble("denominator").Bind(denom => 
       Div(num, denom))); 
    } 

    public static void TestLoop() 
    { 
     while (true) 
     { 
      // Run a computation that asks the user for two numbers, 
      // divides them and then prints out the result. 
      Throws<string, double> t = Interact(); 

      // Notice how the return type forces you to address the 
      // error if you want to get to the value. 
      if (t.IsError) 
      { 
       Console.WriteLine("Error: {0}", t.Error); 
      } 
      else 
      { 
       Console.WriteLine("Success: {0}", t.Result); 
      } 
     } 
    } 
} 
+0

*“用不同的成功类型的值可组成,但它们必须都具有相同的失败类型。” *不听起来正确 - 然后什么是monadic类型? –

+0

我想说的是投掷可以用投掷组合但投掷和投掷不能。 – jaket