2

我的问题

我指的是一个基本上执行以下操作的函数(模const&完美转发,或任何适当的):

auto constexpr dollar = [](auto f, auto x){ return f(x); }; // Why calling it "dollar"? Keep reading...

这样的功能只能通过 Boost.Hana 表达吗?

为什么我会想到它?

在Haskell中,存在这样一个函数,它被调用($)$中缀形式),其定义如下(源码

($) :: forall r a (b :: TYPE r). (a -> b) -> a -> b
f $ x =  f x

并且您可以将第二行简单地写为以下任一

(f $) = f
($) f = f

其中第二种形式显然与(identity function)($)基本相同id

id :: a -> a
id x = x

只是带有强制第一个参数是函数类型a -> b和第二个参数类型的签名a

事实上,在 Haskell 中申请fx可以通过编写这个来完成

f `id` x

即使用`id`而不是$

这和韩有什么关系?

由于 Hana确实提供了一个id函数,我想知道是否可以使用它(可能与其他东西一起)来定义一个函数应用程序实用程序,而无需在本文顶部手动编写 lambda。

困难的部分

这里的难点在于,当你用f `id` xHaskell 编写代码时,争论你是传递 1 个参数还是 2 个参数并没有多大意义id,因为默认情况下所有函数都是柯里化的。

这在 C++ 中是不正确的。例如我可以这样做:

#include <boost/hana/functional/id.hpp>
#include <iostream>
using boost::hana::id;
int main() {
    auto plus1 = [](int x){ return x + 1; };
    std::cout << id(plus1)(3) << std::endl; // prints 4
}

看起来很像id被咖喱并且一个接一个地而不是一起给出两个输入,但这不是真的。只是那id(plus1)正在返回plus1,它被喂养了3。我不知道如何获得以下(相当于plus1 `id` 3id plus1 3在 Haskell 中)的工作:

    std::cout << id(plus1, 3) << std::endl; // doesn't even compile obviously

谜题的真正由来

在阅读了 To Mock a Mockingbird之后,我想知道:“如何仅使用 Boost.Hana 在 C++ 中实现 Thrush?” (而 Thrush 是boost::hana::flip函数应用运算符的 ped 版本。)


¹实际上,如果要编写应用程序链,这并不完全相同,因为这两个运算符具有不同的关联性,所以f $ g $ x == f `id` (g `id` x),但这与问题无关,我相信。

4

0 回答 0