开始使用language.ext(功能C#)

时间:2017-04-26 19:46:26

标签: c# functional-programming

我正在尝试学习更多关于函数式编程的知识,使用language.ext(C#)库作为起点。我正在尝试使用一个Either monad,但有一些我想念的东西。请参阅一个简单的例子:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Dates
{
    public class AssignmentDate
    {

        public static Either<string, AssignmentDate> Create(DateTime date)
        {
            if (date < MinValue)
                return Left<string, AssignmentDate>("date out of range");

            return Right<string, AssignmentDate>(date);
        }

        public static DateTime MinValue => new DateTime(1950, 1, 1);
    }
}

类型Left&lt;&gt;和对&lt;&gt;无法解决。我显然错过了什么,但是什么?我使用的是Either&lt;&gt;是否正确?这是使用Either&lt;&gt ;?时返回的正确方法吗?任何人都可以指出更多的language.ext示例吗?非常感谢您提供的任何帮助。

2 个答案:

答案 0 :(得分:3)

我失踪了 - “使用静态LanguageExt.Prelude;”不知道为什么,但Visual Studio对此有点不同,我在对象浏览器中找不到任何对Left或Right的引用。

答案 1 :(得分:3)

我是Language-Ext的作者。 LeftRight是构造函数,而不是它们自己的类型,它们都构造了Either<L, R>。许多类型在静态类Prelude中都有构造函数,这就是为什么需要对它进行using static的原因。它不是命名空间而是类。

您可以写下:Prelude.Left<L, R>(...)Prelude.Right<L, R>(...)

这是为了模拟像F#这样的函数式语言中的代数数据类型(ADT),Either可以这样定义:

type Either<'l, 'r> =
  | Left of l
  | Right of r

允许您像Either那样构建Right(x)

其他构造函数有:Some(x) NoneOption List(x,y,z)LstSet(x,y,x)SetPrelude,等。

using static类可以很容易地将一大堆基本功能包含在一个using static LanguageExt.Either中,而不必包含using static LanguageExt.Optionpublic static Either<string, AssignmentDate> Create(DateTime date) => date < MinValue ? Left<string, AssignmentDate>("date out of range") : Right<string, AssignmentDate>(date); 等。

顺便说一下,编写示例的更实用的方法是:

    from /home/user/.rvm/rubies/ruby-2.2.4/lib/ruby/site_ruby/2.2.0/rubygems/core_ext/kernel_require.rb:54:in `require'

原因是三元运算符是一个表达式,而您使用多个语句来获取结果。如果您正在学习函数式编程,那么您应该尽可能地尝试使用表达式。例外情况是您需要声明局部变量,但大多数情况下您可以在C#中使用纯表达式。如果表达式太大,请将它们分解为更小的函数。函数式编程的一个副作用是你的函数会变得越来越小;有时只有单行事务。