在 C# 中实现 Either 申请时遇到问题
Trouble Implementing Apply for Either in C#
我正在努力 Functional Programming in C# by Enrico Buonanno
我将如何在 C# 中实现 Apply for Either monad?我尝试了以下不进行类型检查的操作:
using System;
using Xunit;
using LaYumba.Functional;
using static LaYumba.Functional.F;
namespace ch8
{
public class UnitTest1
{
[Fact]
public void Ex1()
{
Func<int, int, int> add = (x, y) => x + y;
var option = Some(add)
.Apply(3)
.Apply(2);
Assert.Equal(Some(5), option);
var either = Left(add)
.Apply(3) // does not type check
.Apply(2);
Assert.Equal(Left(5), either);
}
}
public static class Ext
{
public static Either<L, R> Apply<L, R>(
this Either<L, Func<R, R>> source, Either<L, R> target)
=> source.Match(
l => Left(l),
f => target.Match<Either<L, R>>(
l => Left(l),
r => Right(f(r))
));
}
}
我收到以下错误:
watch : Started
Build started, please wait...
UnitTest1.cs(22,16): error CS1061: 'Either.Left<Func<int, int, int>>' does not contain a definition for 'Apply' and no extension method 'Apply' accepting afirst argument of type 'Either.Left<Func<int, int, int>>' could be found (are you missing a using directive or an assembly reference?) [/ch8/ch8/ch8.csproj]
UnitTest1.cs(25,26): error CS1503: Argument 1: cannot convert from 'LaYumba.Functional.Either.Left<int>' to 'string' [/ch8/ch8/ch8.csproj]
UnitTest1.cs(25,35): error CS1503: Argument 2: cannot convert from 'LaYumba.Functional.Either<L, R>' to 'string' [/ch8/ch8/ch8.csproj]
watch : Exited with error code 1
watch : Waiting for a file to change before restarting dotnet...
我做错了什么?
我是这本书的技术校对者,所以如果其中有任何错误,那是我的错:) 书中的很多内容都是基于我的库 language-ext 并且显然是函数式编程技术一般。如果您需要,那里有一个完全成熟的 Either
实现。
但是,对于您的示例,您几乎可以肯定(目前无法检查,我在火车上)应该使用 Right(add)
而不是 Left(add)
作为 Right
是成功路由,Left
是失败路由。
因此您应该断言结果等于 Right(5)
我已经有一段时间没看过这本书了,但我假设 Left
returns Either.Left<L>
没有相同的 API作为 'success' 路线。
如果您将 Left(add)
转换为 Either<L, R>
,那么您会发现图书馆打开了。
Left
和 Right
构造函数必须处理 Either
需要两种类型的事实。所以他们在隐式转换为 Either<L, R>
之前创建 Left<L>
或 Right<R>
的中间值 - 这通常会使您不必编写 Left<L, R>(l)
和 Right<L, R>
( r), 但有时类型会自己绊倒。
无论如何,等我手边有调试器时,我会仔细看看
我正在努力 Functional Programming in C# by Enrico Buonanno
我将如何在 C# 中实现 Apply for Either monad?我尝试了以下不进行类型检查的操作:
using System;
using Xunit;
using LaYumba.Functional;
using static LaYumba.Functional.F;
namespace ch8
{
public class UnitTest1
{
[Fact]
public void Ex1()
{
Func<int, int, int> add = (x, y) => x + y;
var option = Some(add)
.Apply(3)
.Apply(2);
Assert.Equal(Some(5), option);
var either = Left(add)
.Apply(3) // does not type check
.Apply(2);
Assert.Equal(Left(5), either);
}
}
public static class Ext
{
public static Either<L, R> Apply<L, R>(
this Either<L, Func<R, R>> source, Either<L, R> target)
=> source.Match(
l => Left(l),
f => target.Match<Either<L, R>>(
l => Left(l),
r => Right(f(r))
));
}
}
我收到以下错误:
watch : Started
Build started, please wait...
UnitTest1.cs(22,16): error CS1061: 'Either.Left<Func<int, int, int>>' does not contain a definition for 'Apply' and no extension method 'Apply' accepting afirst argument of type 'Either.Left<Func<int, int, int>>' could be found (are you missing a using directive or an assembly reference?) [/ch8/ch8/ch8.csproj]
UnitTest1.cs(25,26): error CS1503: Argument 1: cannot convert from 'LaYumba.Functional.Either.Left<int>' to 'string' [/ch8/ch8/ch8.csproj]
UnitTest1.cs(25,35): error CS1503: Argument 2: cannot convert from 'LaYumba.Functional.Either<L, R>' to 'string' [/ch8/ch8/ch8.csproj]
watch : Exited with error code 1
watch : Waiting for a file to change before restarting dotnet...
我做错了什么?
我是这本书的技术校对者,所以如果其中有任何错误,那是我的错:) 书中的很多内容都是基于我的库 language-ext 并且显然是函数式编程技术一般。如果您需要,那里有一个完全成熟的 Either
实现。
但是,对于您的示例,您几乎可以肯定(目前无法检查,我在火车上)应该使用 Right(add)
而不是 Left(add)
作为 Right
是成功路由,Left
是失败路由。
因此您应该断言结果等于 Right(5)
我已经有一段时间没看过这本书了,但我假设 Left
returns Either.Left<L>
没有相同的 API作为 'success' 路线。
如果您将 Left(add)
转换为 Either<L, R>
,那么您会发现图书馆打开了。
Left
和 Right
构造函数必须处理 Either
需要两种类型的事实。所以他们在隐式转换为 Either<L, R>
之前创建 Left<L>
或 Right<R>
的中间值 - 这通常会使您不必编写 Left<L, R>(l)
和 Right<L, R>
( r), 但有时类型会自己绊倒。
无论如何,等我手边有调试器时,我会仔细看看