接受预期Func的FSharpFunc

时间:2014-04-23 06:05:08

标签: .net f# extension-methods func

this question中所述,期望Func的方法不接受F#函数值。

什么是重载方法以使其接受F#函数值的好方法?

5 个答案:

答案 0 :(得分:6)

我知道这不是你要问的问题,而是直接尝试用C#编写的代码来支持F#(因为我得到你正在尝试做的印象),它会是<强大>更具惯用性,提供一个小的适配器模块,使F#的功能组合更容易。

有很多这样的示例,例如FSharp.Reactive,它提供了一些功能,可以更轻松地使用F#中的Reactive Extensions

例如,如果您想从F#访问Enumerable.All可以编写一个小适配器功能,例如

let all f (s : 'a seq) = s.All (fun x -> f x)

你可以这样使用: -

seqA |> all abc

但是,对于All,您可以使用内置的F#函数:

seqA |> Seq.forall abc

答案 1 :(得分:2)

使用初始问题中的代码,最简单的解决方案是创建预期委托的实例(在本例中为Func<int, bool>)并将函数值作为参数传递。

let seqA = { 1..10 }
let abc = fun n -> n > 0
seqA.All (Func<_,_> abc)

Patryk在他的评论中注意到了这种语法,但我想我会添加一个关于真实情况的解释。

答案 2 :(得分:1)

不只是创建一个Func&lt; &gt;够了吗?

let doSomethingWithFunc (f : System.Func<_,_>) =
    42

let doSomethingWithFSharpFunc (f : 'a -> 'b) =
    System.Func<_,_>(f) |> doSomethingWithFunc

(fun x -> 42) |> doSomethingWithFSharpFunc

答案 3 :(得分:1)

这是另一种方法:

open System
open System.Collections.Generic
open System.Linq

type IEnumerable<'T> with
    member this.All(pred: 'T -> bool) = this.All(Func<_,_> pred)

let even n = n % 2 = 0

let seqA = seq { 0..2..10 }

seqA.All(even) |> printfn "%A"

答案 4 :(得分:0)

以下是将F#函数值传递给IEnumerable.All的示例:

open System.Linq
open IEnumerableAllFSharpFunc

let seqA = seq { 1..10 }

let abc n = n > 0

seqA.All abc |> printfn "%A"

IEnumerable.All上提供此扩展方法:

using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.FSharp.Core;

namespace IEnumerableAllFSharpFunc
{
    public static class Utils
    {
        public static bool All<T>(this IEnumerable<T> seq, FSharpFunc<T, bool> pred)
        {
            var converter = FSharpFunc<T, bool>.ToConverter(pred);

            Func<T, bool> func = (elt) => converter(elt);

            return seq.All(func);
        }
    }
}

欢迎更优雅的方法。 : - )