我正在翻译这个F# source用于铁路导向编程to 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
函数(我认为我已正确translated)接受带有签名('a -> 'b -> 'c)
的函数作为第一个参数,但绑定到mapper
时绑定部分应用我有问题理解使用过的lambda函数。
我通常使用these helpers进行部分应用,但我无法将此F#代码翻译为C#。
答案 0 :(得分:3)
你的Lift2期待一个curried函数,但传递给SelectMany的映射器不是curry。让我们来讨论它:
for ( i = 0; i < n; i++ ) // Code for LIS
{
for ( j = 0; j < i; j++ )
{
if (arr[i] > arr[j] && lis[i] < lis[j] + 1)
lis[i] = lis[j] + 1;
}
}
for ( i = 0; i < n; i++ ) // Code for LDS
{
for ( j = 0; j < i; j++ )
{
if (arr[i] < arr[j] && lds[i] < lds[j] + 1)
lds[i] = lds[j] + 1;
}
}
答案 1 :(得分:1)
通常,lift2
采用简单类型'a
和'b
的两个参数的函数,并生成一个适用于包装类型M<'a>
和{{1}的函数}。否则,您可以将其视为三个参数:一个函数优于简单类型和两个包装值,展开这些值,将函数应用于它们并包装结果。
假设您的功能已从F#正确移植,M<'b>
的正文将如下所示:
SelectMany
奇怪的return Lift2(mapper, this, Bind(func, this));
存在于F#版本中,因为Invokes
不适用于C#,您必须明确调用Funcs
。此外,由于它没有结果,Invoke
无法直接传递到mapper.Invoke
- 这就是为什么它被包裹在一个curried函数中。