平面地图歧视工会

时间:2016-09-08 11:27:35

标签: c#

我在Github上使用了一个名为OneOf的lib。

基本上你有一种类型可以是多种类型之一,但是以静态安全的方式。

以下是我试图实现的一个例子 我输入了A<T1, T2, T3, T4>,输入了B<T1, T2, T3>,我想要&#34; flapmap&#34;键入A到类型A.因为类型A可以接受来自B的任何单个T,所以它应该是可能的。

编译器强制我从B中提取每个T,然后将其分配给A,正如您在下面的愚蠢的x => x lambdas所看到的那样。

我也不想结束像A<B<T1, T2, T3>, T4>这样的人 那么有人会想到这些OneOf类型的SelectMany吗?

using OneOf;
using System;
using System.IO;

namespace ScratchPad
{
    class Program
    {
        struct BadRequest { }
        struct Error { }
        struct NotFound { }

        static void Main(string[] arg)
        {
            string result = GetFile(@"c:\data\foo.txt").Match(
                text => text,
                badRequest => "filepath cannot be null",
                notFound => "filepath does not exist",
                error => "an error occurred"
            );

            Console.WriteLine(result);
        }

        static OneOf<string, BadRequest, NotFound, Error> GetFile(string filepath)
        {
            OneOf<string, BadRequest, NotFound, Error> response = new BadRequest();

            if (filepath != null)
            {
                // How can I make the type from ReadText() automatically convert to the type of the response local variable, without having to write these silly lambda?
                response = ReadText(filepath).Match<OneOf<string, BadRequest, NotFound, Error>>(x => x, x => x, x => x); 
            }

            return response;
        }

        static OneOf<string, NotFound, Error> ReadText(string filepath)
        {
            OneOf<string, NotFound, Error> response = new NotFound();

            try
            {
                if (File.Exists(filepath))
                {
                    response = File.ReadAllText(filepath);
                }
            }
            catch
            {
                response = new Error();
            }

            return response;
        }
    }
}

1 个答案:

答案 0 :(得分:0)

扩展方法可能是一种方式。

一个例子,就在我的脑海中,转换3到4种类型:

public static class OneOfExtensions
{
  public static OneOf<T1, T2, T3, T4> ConvertOneOf<T1, T2, T3, T4>(this OneOf<T1, T2, T3> oneOf)
  {
    return oneOf.Match<OneOf<T1, T2, T3, T4>>(x => x, x => x, x=> x);
  }

  public static OneOf<T1, T2, T3, T4> ConvertOneOf<T1, T2, T3, T4>(this OneOf<T1, T2, T4> oneOf)
  {
    return oneOf.Match<OneOf<T1, T2, T3, T4>>(x => x, x => x, x=> x);
  }

  public static OneOf<T1, T2, T3, T4> ConvertOneOf<T1, T2, T3, T4>(this OneOf<T1, T3, T4> oneOf)
  {
    return oneOf.Match<OneOf<T1, T2, T3, T4>>(x => x, x => x, x=> x);
  }

  public static OneOf<T1, T2, T3, T4> ConvertOneOf<T1, T2, T3, T4>(this OneOf<T2, T3, T4> oneOf)
  {
    return oneOf.Match<OneOf<T1, T2, T3, T4>>(x => x, x => x, x=> x);
  }
}

它不是特别漂亮,但它应该保持你的代码相对干净。