在MaybeMonad

时间:2018-03-13 06:10:15

标签: c# monads

我正在尝试这个site的示例,但遇到以下推理问题。

这个例子可能是Monads,可以通过连续的空值检查和线性方式编写代码来保存。

  

无法从用法中推断出方法Maybe<Customer>.Bind<TO>(Func<Customer, Maybe<TO>>)的类型参数。尝试指定   明确地输入参数。

Maybe.cs

using System;

namespace Monads
{
    public class Maybe<T> where T : class
    {
        private readonly T value;

        public Maybe(T someValue) 
        {
            if(someValue == null) 
                throw new ArgumentNullException(nameof(someValue));
            this.value = someValue;
        }

        private Maybe(){}

        public Maybe<TO> Bind<TO>(Func<T, Maybe<TO>> func) where TO : class
        {
            return value != null ? func(value) : Maybe<TO>.None();
        }

        public static Maybe<T> None() => new Maybe<T>();
    }
}

IMonadicRepository

namespace Monads
{
    public interface IMonadicRepository
    {
       Maybe<Customer> GetCustomer(int id);
       Maybe<Address> GetAddress(int id);
    }
}

Repository.cs

namespace Monads {
    public class Repository : IMonadicRepository
    {
        public Maybe<Customer> GetCustomer(int id) {
            return new Maybe<Customer>(new Customer(id));
        }

        public Maybe<Address> GetAddress(int id)
        {
            return new Maybe<Address>(new Address(id));
        }
    }
}

Customer.cs

namespace Monads
{
    public class Customer 
    {
        public Customer(int id) {
        }

        public Address Address {get; set;}
    }
}

Address.cs

namespace Monads 
{
    public class Address 
    {
        public Address(int id) {
        }
    }
}

用法 - Programs.cs

namespace Monads
{
    class Program
    {
        static void Main(string[] args)
        {
            IMonadicRepository repository = new Repository();
            repository.GetCustomer(1)
                .Bind(customer => customer.Address); // error
        }
    }
}

错误:无法从使用情况推断方法'Maybe.Bind(Func>)'的类型参数。尝试明确指定类型参数。

1 个答案:

答案 0 :(得分:0)

您的问题是,在.Bind(customer => customer.Address)行,customer.Address的类型为Address。但是,函数Bind需要一个返回Maybe<Address>而不是Address的lambda。

我不确定这是否是正确的方法,但一种选择是使用帖子中定义的Return扩展方法:

repository.GetCustomer(1)
    .Bind(c => c.Address.Return());

为了完成,我也将其复制到这里:

public static class MaybeExtensions
{
    public static Maybe<T> Return<T>(this T value) where T : class
    {
        return value != null ? new Maybe<T>(value) : Maybe<T>.None();
    }
}