Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/linq/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/fsharp/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
F使用Linq查询的自定义类型的Linq扩展方法_Linq_F#_Extension Methods_Monads - Fatal编程技术网

F使用Linq查询的自定义类型的Linq扩展方法

F使用Linq查询的自定义类型的Linq扩展方法,linq,f#,extension-methods,monads,Linq,F#,Extension Methods,Monads,在C中,我可以通过实现Select和SelectMany的扩展方法,在Linq查询中为自定义类型启用一元合成,例如: public static或选择this或@this,Func fn=>@this.Mapfn; public static或SelectManythis@this,Func fn=>@this.FlatMapfn; public static ory SelectManythis@this,Func fn,Func select=>@this.flatmap=>fna.flat

在C中,我可以通过实现Select和SelectMany的扩展方法,在Linq查询中为自定义类型启用一元合成,例如:

public static或选择this或@this,Func fn=>@this.Mapfn; public static或SelectManythis@this,Func fn=>@this.FlatMapfn; public static ory SelectManythis@this,Func fn,Func select=>@this.flatmap=>fna.flatmap=>selecta,b.ToEither; 第三种扩展方法是在与Haskell中的liftM函数类似的基础上启用Linq查询中的一元合成,例如:

要么提升2,要么提升m1,要么提升m2,要么提升f{ 从m1中的a返回 从b到m2 选择Rightfa,b; } 然而,我的问题与实现F中的结果有关,方法是为自定义的任意一种类型实现扩展方法,以便在Linq查询中启用一元组合

以下是我对这两种类型的定义:

键入或= |左 |r的权利 首先,我为map和flatmap添加了一个函数,包括map as和flatmap as>>=and=righter的自定义操作符 让rmap f e= 匹配 |左->左 |右->右 设mapfe=rmapfe 设内联ef=映射ef 让内联>常数 设lflatmap f e= 匹配 |左左->左 |右->右 让rflatmap f e= 匹配 |左->左 |右->右 设flatmap f e=rflatmap f e 让内联>>=f e=flatmap f e 让inline='s=map f e 静态成员内联选择manye:eather,f:'r->eather=flatmap f e 静态成员内联选择manye:or,f:'r->or,选择:'r->'s->'t=f>>=e=or。右选择e,s 问题是当我试图使用它来实现liftM、liftM2。。。函数它似乎没有选择这些扩展方法;相反,它使用System.Linq.IQueryable的扩展方法,而不是我对Linq的自定义扩展方法,例如SelectMany

设liftM f m1=query{ 对于m1中的a,请执行以下操作: 选择Rightfa } liftM的类型解析为:

liftM: f:a->b,
m1:System.Linq.IQueryableC查询语法基于语法转换,如您的示例所示,在F中,每个monad实例由一个关联的构建器类表示,该类实现了所需的操作,例如seq、async、query。您需要创建一个实现所需操作的任意生成器。对于您的示例,您只需要一个最小的实现:

type EitherBuilder() = 
        member x.Bind(e, f) = flatmap f e
        member x.Return(value) = _return value
        member x.ReturnFrom(e) = e

let either = new EitherBuilder()
然后您可以使用它来实现liftM:


C查询语法基于语法转换,如您的示例所示,在F中,每个monad实例由一个关联的构建器类表示,该类实现所需的操作,例如seq、async、query。您需要创建一个实现所需操作的任意生成器。对于您的示例,您只需要一个最小的实现:

type EitherBuilder() = 
        member x.Bind(e, f) = flatmap f e
        member x.Return(value) = _return value
        member x.ReturnFrom(e) = e

let either = new EitherBuilder()
然后您可以使用它来实现liftM:


您是在尝试扩展查询表达式,还是只希望这两种类型都使用一元表达式?在这种情况下,您应该实现实现操作的a,然后您可以在C中执行,例如,让liftM f m1=任{let!a=m1;返回f a}。上述扩展方法的实现在Linq查询中按照预期工作,无需任何其他实现。F对我来说是新事物,所以很可能我没有使用正确的语法来访问这两种类型的三个自定义Linq查询扩展。我能得到的是,查询将允许我输入Linq查询;然而,这似乎只适用于IQueryable。F没有像C中那样无缝地实现Linq extensions方法。F中需要自定义表达式生成器吗?您是在尝试扩展查询表达式,还是只需要为这两种类型使用一元表达式?在这种情况下,您应该实现实现操作的a,然后您可以在C中执行,例如,让liftM f m1=任{let!a=m1;返回f a}。上述扩展方法的实现在Linq查询中按照预期工作,无需任何其他实现。F对我来说是新事物,所以很可能我没有使用正确的语法来访问这两种类型的三个自定义Linq查询扩展。我能得到的是,查询将允许我输入Linq查询;然而,这似乎只适用于IQueryable。F没有像C中那样无缝地实现Linq扩展方法。F中是否需要自定义表达式生成器?