问题标签 [lifting]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
4 回答
442 浏览

python - 在 python 中使用装饰器将 f(x) 转换为 f([x])

这是我几年前写的。当你用它装饰任何功能f(X)时,@foo它会变成 f(list of Xs).

这个过程叫什么?它是什么?它的函数式编程名称是什么?

它不是咖喱。我知道简单map9(f,list of Xs)可以做到。

什么是装饰器/装饰操作在数学上称为?

0 投票
4 回答
3116 浏览

c# - C# Lambda 性能问题/可能性/指南

我正在使用各种 lambda 表达式语法测试性能差异。如果我有一个简单的方法:

然后这里有一些与point参数相关的变量提升,因为从 lambda 的角度来看,它是一个自由变量。如果我将这个方法调用一百万次,是保持原样还是以任何方式更改它以提高其性能会更好吗?

我有哪些选择,哪些实际上可行?据我了解,我必须摆脱自由变量,因此编译器不必创建闭包类并在每次调用此方法时实例化它。与非封闭版本相比,这种实例化通常需要大量时间。

问题是我想提出一些通常可以工作的lambda 编写指南,因为每次我编写一个深受打击的 lambda 表达式时,我似乎都在浪费一些时间。我必须手动测试它以确保它可以工作,因为我不知道要遵循什么规则。

替代方法

& 示例控制台应用程序代码

我还编写了不需要任何变量提升的相同方法的不同版本(至少我认为不需要,但如果是这样的话,理解这一点的人请告诉我):

在这里查看要点。只需创建一个控制台应用程序并将整个代码复制到块Program.cs内的文件中namespace。您将看到第二个示例要慢得多,即使它不使用自由变量。

一个矛盾的例子

我想构建一些lambda 最佳使用指南的原因是我以前遇到过这个问题,令我惊讶的是,当使用谓词构建器lambda 表达式时,一个工作得更快。

现在解释一下。我在这里完全迷失了,因为当我知道我的代码中有一些大量使用方法时,我可能根本不会使用 lambdas。但我想避免这种情况并深入了解这一切。

编辑

您的建议似乎不起作用

我尝试实现一个自定义查找类,它在内部工作类似于编译器对自由变量 lambda 所做的工作。但是我没有实现闭包类,而是实现了模拟类似场景的实例成员。这是代码:

有趣的是,它的运行速度与慢速版本一样慢。我不知道为什么,但它似乎除了快速之外什么也没做。它重用了相同的功能,因为这些附加成员是同一个对象实例的一部分。反正。我现在非常困惑

我已经用这个最新的添加更新了Gist 源,所以你可以自己测试。

0 投票
1 回答
1383 浏览

scala - 是否可以在 Scala 中实现 liftM2?

在 Haskell 中,liftM2可以定义为:

我想把它翻译成 Scala。我的第一次尝试如下:

我猜这可能是最明显的方式失败:“值 flatMap 不是类型参数 M[T1] 的成员”。是的,我没有指出这M[_]是某种单子。所以接下来我尝试定义一些结构类型,例如:

...并拥有M[A] <: Monad[A]. 但这不起作用,因为 Scala 没有递归结构类型。

所以接下来我尝试的几件事涉及类似于M[A] <: FilterMonadic[A, _]. 这些都失败了,可能是因为我无法为CanBuildFrom.

我在 StackOverflow 上能找到的最密切相关的问题是这个问题,涉及递归结构类型以及如何在 Scala 中模仿 Haskell 的类型类。但是这种方法需要定义从您关心的每种类型到定义类型类的特征的隐式转换,在这种情况下这似乎非常循环......

有什么好方法可以做我想做的事吗?

0 投票
1 回答
1154 浏览

haskell - 在 Haskell 中提升高阶函数

我正在尝试构建一个类型的函数:

t单子变压器在哪里。具体来说,我有兴趣这样做:

我摆弄了一些 Haskell 魔法库,但无济于事。我怎样才能做到正确,或者在我没有找到的地方有现成的解决方案?

0 投票
1 回答
4510 浏览

c# - 如何分解成员访问表达式链?

短版(TL;DR):

假设我有一个表达式,它只是一个成员访问运算符链:

您可以将此表达式视为子表达式的组合,每个子表达式都包含一个成员访问操作:

我想要做的是分解e成这些组件子表达式,以便我可以单独使用它们。

更短的版本:

如果我有表情的话x => x.foo.bar,我已经知道怎么打断了x => x.foo。我怎样才能拉出另一个子表达式,foo => foo.bar

为什么我要这样做:

我正在尝试在 C# 中模拟“提升”成员访问运算符,例如CoffeeScript 的存在访问运算符?.。Eric Lippert 曾表示曾考虑为 C# 使用类似的运算符,但没有预算来实施它。

如果 C# 中存在这样的运算符,您可以执行以下操作:

如果链的任何部分target.foo.bar.baz结果为 null,那么整个事情将评估为 null,从而避免 NullReferenceException。

我想要一个Lift可以模拟这种事情的扩展方法:

我试过的:

我有一些可以编译的东西,它有点工作。但是,它是不完整的,因为我只知道如何保留成员访问表达式的左侧。我可以x => x.foo.bar.baz变成x => x.foo.bar,但我不知道如何保持bar => bar.baz

所以它最终会做这样的事情(伪代码):

这意味着表达式中最左边的步骤会被一遍又一遍地评估。如果它们只是 POCO 对象的属性,可能没什么大不了的,但是将它们转换为方法调用,效率低下(和潜在的副作用)变得更加明显:

编码:

这是受到这个答案的粗略启发。


提升方法的替代方法,以及为什么我不能使用它们:

也许单子

优点:
  1. 使用在函数式编程中流行的现有模式
  2. 除了提升会员访问权限外,还有其他用途
缺点:
  1. 它太冗长了。每次我想向下钻取几个成员时,我不想要大量的函数调用链。即使我实现SelectMany并使用查询语法,恕我直言,这看起来会更混乱,而不是更少。
  2. 我必须手动将x.foo.bar.baz其重写为各个组件,这意味着我必须在编译时知道它们是什么。我不能只使用来自变量的表达式,例如result = Lift(expr, obj);.
  3. 不是为我想要做的事情而设计的,而且感觉不是完美的契合。

表达访客

将 Ian Griffith 的 LiftMemberAccessToNull 方法修改为通用扩展方法,可以按照我的描述使用。代码太长,无法在此处包含,但如果有人感兴趣,我会发布 Gist。

优点:
  1. 遵循result = target.Lift(x => x.foo.bar.baz)语法
  2. 如果链中的每个步骤都返回引用类型或不可为空的值类型,则效果很好
缺点:
  1. 如果链中的任何成员是可为空的值类型,它就会窒息,这确实限制了它对我的用处。我需要它为Nullable<DateTime>会员工作。

试着抓

这是最明显的方式,如果找不到更优雅的方式,我会使用它。

优点:
  1. 这很简单。
  2. 代码的用途很明显。
  3. 我不必担心边缘情况。
缺点:
  1. 它丑陋而冗长
  2. try/catch 块是一个不平凡的*性能影响
  3. 这是一个语句块,所以我不能让它为 LINQ 发出表达式树
  4. 感觉像是认输

我不会说谎;“不认输”是我这么固执的主要原因。我的直觉认为必须有一种优雅的方式来做到这一点,但找到它一直是一个挑战。我不敢相信访问表达式的左侧如此容易,但右侧却几乎无法访问。

我在这里真的有两个问题,所以我会接受任何可以解决任何一个问题的方法:

  • 保留双方的表达式分解,具有合理的性能,适用于任何类型
  • 空传播成员访问

更新:

空传播成员访问计划包含 C# 6.0中。不过,我仍然想要表达式分解的解决方案。

0 投票
2 回答
318 浏览

haskell - 为什么我不能使用 iterate 重复应用地图?

我已经意识到,当我嵌套了数据结构时,我一直在手动编写代码来深入研究它们。像这样:

所以我突然想到,我应该能够使用更高阶的函数自动构造一个函数来深入研究我的嵌套数据结构:

它让我印象深刻

  1. 我知道它会在预期的位置找到一个列表……别的
  2. 我不知道如何解决这个问题 - 我是否应该编写代码来重复应用程序,即使那是我认为 iterate 的用途?
  3. 这似乎类似于“提升”的概念——但我不知道如何应用这种直觉。
0 投票
1 回答
176 浏览

scala - 自动提升scala中的表达式以实现并发

我想以透明的方式并行评估任何函数的参数(没有任何源级别更改)。

例如 -
    c = f(a, b)应该导致:
    a并被b并行评估,然后调用f.

一种方法是将上述表达式转换为:

(这样f: a -> b -> c就变成了f: Future<a> -> Future<b> -> Future<c>)这样c' = f'(a', b')

这可以在scala中做到吗?

0 投票
1 回答
705 浏览

haskell - 将 Kleisli 箭头提升到 IO?

如果我有以下两个 Kleisli 箭头:

我希望能够写出类似的东西:

这当然行不通,因为String不匹配IO String. 另一方面,可以同时定义stdoutProcessA和定义writeToFileAtype Kleisli IO ...,但是我将无法用 type 的箭头组合它们Kleisli Maybe ...,这是我需要的其他事情。

我对箭头还不是很有经验,所以我可能遗漏了一些明显的东西。如何进行上述操作?

0 投票
1 回答
163 浏览

haskell - 变形金刚下的转型

目前我在使用 monad 转换器时遇到了一些困难。我正在定义一些使用变压器的不同的非确定性关系。不幸的是,我无法理解如何将一种有效的模型清晰地转换为另一种。

假设这些关系是“foo”和“bar”。假设“foo”将 As 和 Bs 与 Cs 联系起来;假设“bar”将 Bs 和 Cs 与 Ds 联系起来。我们将根据“foo”来定义“bar”。更有趣的是,这些关系的计算将以不同的方式失败。(因为 bar 关系依赖于 foo 关系,所以它的失败案例是一个超集。)因此我给出了以下类型定义:

然后,我希望能够使用以下函数签名编写关系:

我的问题是,在编写“bar”的定义时,我需要能够从“foo”关系接收错误并在“bar”空间中正确表示它们。所以我会很好的形式的功能

我什至可以通过运行 ListT,映射到 EitherT,然后重新组装 ListT 来编写那个小野兽(因为碰巧 m [a] 可以转换为 ListT ma)。但这似乎……很乱。

我不能只运行一个变压器,在它下面做一些事情,然后通常“放回去”,这是有充分理由的;我运行的变压器可能会产生影响,我无法神奇地撤消它们。但是有什么方法可以让我将一个函数提升到一个变压器堆栈中足够远的地方来为我做一些工作,这样我就不必编写convert上面显示的函数了?

0 投票
3 回答
1243 浏览

scala - Scala奇怪的隐式装箱转换错误

有人可以告诉我为什么以下不起作用?

产生此错误: