考虑这段代码:
public class Foo
{
public int a { get; set; }
public int b { get; set; }
}
private void Test()
{
List<Foo> foos = new List<Foo>();
foos.Add(new Foo());
foos.Add(new Foo());
Expression<Func<Foo, int>> exp0 = f => f.a * f.b;
Expression<Func<int>> exp1 = () => foos[0].a * foos[0].b;
Expression<Func<int>> exp2 = () => foos[1].a * foos[1].b;
}
Run Code Online (Sandbox Code Playgroud)
你怎么能把exp0它变成两个与exp1和相同的表达式exp2.请注意,我不想仅为exp0每个Fooin 评估foos,而是获得两个新表达式.
[更新]:
基本上,我希望能够扩大或"扁平化"传递给A的表达Linq扩展方法,如Sum入枚举每个项目一个表达,因为这些枚举是静态的,因为我已经有代码读取不表达获取参数(然后将它们转换为另一种语言). …
我无法理解函数应用程序如何与haskell中的currying一起工作.如果我有以下功能:
($) :: (a -> b) -> a -> b
Run Code Online (Sandbox Code Playgroud)
我明白要部分应用这个功能,我需要提供(a -> b)函数($第一个参数).
为什么可以先应用一个值(即反向参数)?
($ 0) :: Num a => (a -> b) -> b
Run Code Online (Sandbox Code Playgroud)
我在这里错过了什么?
haskell operators partial-application dollar-sign operator-sections
你可以使用部分应用的运算符传递"除以2"或"减1"等操作,其中"加1"如下所示:
List.map ((+) 1) [1..5];; //equals [2..6]
// instead of having to write: List.map (fun x-> x+1) [1..5]
Run Code Online (Sandbox Code Playgroud)
正在发生的事情是1被应用于(+)作为它的第一个参数,并且列表项被应用为第二个参数.对于加法和乘法,这个参数排序无关紧要.
假设我想从每个元素中减去1(这可能是常见的初学者错误):
List.map ((-) 1) [1..5];; //equals [0 .. -4], the opposite of what we wanted
Run Code Online (Sandbox Code Playgroud)
1被应用于( - )作为它的第一个参数,所以不是(list_item - 1),我得到(1 - list_item).我可以将其重写为添加负数而不是减去正数:
List.map ((+) -1) [1..5];;
List.map (fun x -> x-1) [1..5];; // this works too
Run Code Online (Sandbox Code Playgroud)
我正在寻找一种更具表现力的方式来编写它,例如((-) _ 1),where _表示占位符,就像在Arc语言中一样.这将导致1成为第二个参数-,因此在List.map中,它将评估为list_item - 1.所以如果你想映射divide by 2到列表,你可以写:
List.map ((/) …Run Code Online (Sandbox Code Playgroud) 不久前学习Haskell,我感觉爱上了无点符号,特别方便的部分功能应用 - 只需提供你知道的args.在Clojure,我一直partial都有.我认为在阅读器中使用特殊语法会很好.
看一下示例代码:
; Notation with points:
(map (+ 10 (* % 2)) [1 2 3])
; With partial:
(map (comp (partial + 10) (partial * 2)) [1 2 3])
; Let #[] syntax means partial application in reader:
(map (comp #[+ 10] #[* 2]) [1 2 3])
Run Code Online (Sandbox Code Playgroud)
真是太好了!有这样的事吗?是否有可能定义自定义阅读器宏?
我curry在JavaScript中编写了一个简单的函数,可以在大多数情况下正常工作
const add = curry((a, b, c) => a + b + c);
const add2 = add(2);
const add5 = add2(3);
console.log(add5(5));Run Code Online (Sandbox Code Playgroud)
<script>
const curried = Symbol("curried");
Object.defineProperty(curry, curried, { value: true });
function curry(functor, ...initArgs) {
if (arguments.length === 0) return curry;
if (typeof functor !== "function") {
const value = JSON.stringify(functor);
throw new TypeError(`${value} is not a function`);
}
if (functor[curried] || initArgs.length >= functor.length)
return functor(...initArgs);
const result = (...restArgs) => curry(functor, ...initArgs, ...restArgs);
return …Run Code Online (Sandbox Code Playgroud)javascript haskell lambda-calculus currying partial-application
到目前为止,我见过的所有示例都创建了一个"包装器"函数Basics.+,然后部分应用:
sum x y =
x + y
plusOne =
sum 1
Run Code Online (Sandbox Code Playgroud)
但是,我确信有一种方法可以避免额外的包装.
看这个例子:
def hello(a:String, b:String) = println(a + ":" + b)
val m1 = hello("aaa", _ )
m1("bbb")
Run Code Online (Sandbox Code Playgroud)
它无法编译,我需要将类型添加到partial方法:
val m1 = hello("aaa", _: String)
Run Code Online (Sandbox Code Playgroud)
为什么scala不知道方法的第二个参数hello是String什么?
我刚刚从另一个问题中了解到Haskell被称为curried编程语言,因为它默认使用函数currying.显示此行为的其他语言是什么?
programming-languages functional-programming currying partial-application
考虑定义两个属性的抽象类
abstract class A {
def a: Int
def b: Int
// real A has additional members
}
Run Code Online (Sandbox Code Playgroud)
这是各种案例类的基类,如
case class Foo(a: Int, b: Int) extends A
case class Bar(a: Int, b: Int) extends A
// and many more
Run Code Online (Sandbox Code Playgroud)
目标:我最终希望能够以两种方式创建上述案例类的实例,即
val b1 = Bar(1, 2)
val b2 = Bar(1) has 2
assert(b1 == b2) // must hold
Run Code Online (Sandbox Code Playgroud)
方法:因此,定义一个帮助类来定义has并允许我部分构造As 似乎是合理的
case class PartialA(f: Int => A) {
def has(b: Int) = f(b)
}
Run Code Online (Sandbox Code Playgroud)
问题:当前机制不允许调用, …
我最近一直在研究功能编程,并希望将一些概念带到我的C#世界.我正在尝试编写函数来创建服务(或任何你称之为的服务),而不是创建具有可注入依赖项的类.
我想方设法通过创建一个像这样的静态方法,用两个参数和一个返回参数来部分应用一个函数(与注入依赖项具有相同的效果):
// this makes a func with a single arg from a func with two
static Func<T2, TResult> PartiallyApply<T1, T2, TResult>(
Func<T1,T2, TResult> f,
T1 t1)
{
// use given t1 argument to create a new function
Func<T2, TResult> map = t2 => f(t1, t2);
return map;
}
Run Code Online (Sandbox Code Playgroud)
这工作,但我想传递一个静态方法,如下所示:
static string MakeName(string a, string b) => a + " " + b;
Run Code Online (Sandbox Code Playgroud)
当我尝试连接它时,我得到错误The type arguments for method 'Program.PartiallyApply<T1, T2, TResult>(Func<T1, T2, TResult>, T1)' cannot be inferred …