将f#函数部分应用程序转换为c#
本文关键字:程序转换 应用 函数部 | 更新日期: 2023-09-27 18:03:17
我正在把这个面向铁路编程的f#源代码翻译成c#。
我在翻译这个SelectMany
过载时有困难:
static member inline SelectMany (this:Result<'TSuccess, 'TMessage>, func: Func<_,_>, mapper: Func<_,_,_>) =
let mapper = lift2 (fun a b -> mapper.Invoke(a,b))
let v = bind func.Invoke this
mapper this v
我已经用上面的映射函数签名:
public static Result<TResult, TMessage> SelectMany<TSuccess, TMessage, TValue, TResult>(
this Result<TSuccess, TMessage> result,
Func<TSuccess, Result<TValue, TMessage>> func,
Func<TSuccess, TValue, TResult> mapperFunc)
f# lift2
函数(我认为我已经正确翻译)接受作为第一个参数的函数签名('a -> 'b -> 'c)
,但当绑定到mapper
让绑定部分应用程序我有问题理解使用的lambda函数。
我通常在部分应用程序中使用这些帮助程序,但我无法将这些f#代码转换为c#。
你的Lift2期望一个柯里化的函数,但是传递给SelectMany的映射器没有柯里化。我们来修改一下:
Func<TSuccess, Func<TValue, TResult>> curriedMapper = suc => val => mapperFunc(suc, val);
Func<
Result<TSuccess, TMessage>,
Result<TValue, TMessage>,
Result<TResult, TMessage>
> liftedMapper = (a, b) => Lift2(curriedMapper, a, b);
var v = Bind(func, result);
return liftedMapper(result, v);
一般来说,lift2
接受具有两个简单类型'a
和'b
参数的函数,并产生一个适用于包装类型M<'a>
和M<'b>
的函数。否则,您可以将其视为接受三个参数:一个简单类型的函数和两个包装好的值,对这些值展开包装,对它们应用函数并包装结果。
假设您的函数正确地从f#移植,SelectMany
的主体看起来像这样:
return Lift2(mapper, this, Bind(func, this));
奇怪的Invokes
在f#版本中存在,因为Funcs
不像c#那样适用,你必须显式调用Invoke
。也因为它是未柯化的,mapper.Invoke
不能直接传递给lift2
-这就是为什么它被包装在柯化函数中。