这个概念在 Haskell 中叫什么?

jac*_*bsa 3 monads haskell functional-programming monad-transformers

我正在用 C++ 编写一些相对函数式风格的代码,并试图避免为其起一个坏名字。为此,我尽可能坚持 Haskell 中同构概念的名称。(需要明确的是,我不太了解 Haskell,但阅读它非常有启发性。)

如果我正确地完成了 Haskell 打字,我相信我正在寻找名称的概念将具有以下签名:

someName :: (Monad m1, Monad m2) => (a -> m1 b) -> (m2 a -> m1 m2 b)
Run Code Online (Sandbox Code Playgroud)

这个想法是,您有一个适合用于绑定类型 monad 的函数m1,并将其转换为适合绑定m1包含m2值的值的函数。

我不能很好地编写 Haskell 来给出一个例子,但这里是伪 C++ 说明我想要的,使用std::optionalabsl::StatusOr

// A silly example of a bind function for absl::StatusOr<int>.
absl::StatusOr<int> AddTwoUnless17(int x) {
  if (x == 17) {
    return absl::InternalError("can't add two to 17!")
  }
  
  return x + 2;
}

// Convert AddTwoUnless17 into a bind function for
// absl::StatusOr<std::optional<int>>. The resulting logic is:
//
//  *  If the input is an error, propagate that error.
//  *  If the input is std::nullopt, return std::nullopt.
//  *  If the input is 17, return an error.
//  *  Otherwise return the input plus two.
//
// Here we have:
//
//     m1: absl::StatusOr
//     m2: std::optional
//
std::function<absl::StatusOr<std::optional<int>>(std::optional<int>) f =
    someName(AddTwoUnless17);

CHECK_EQ(
    absl::CancelledError(),
    f(absl::StatusOr<std::optional<int>>(absl::CancelledError())));

CHECK_EQ(
    std::nullopt,
    f(absl::StatusOr<std::optional<int>>(std::nullopt)));

CHECK_EQ(
    absl::InternalError("can't add two to 17!"),
    f(absl::StatusOr<std::optional<int>>(17)));

CHECK_EQ(
    13,
    f(absl::StatusOr<std::optional<int>>(11)));
Run Code Online (Sandbox Code Playgroud)

这个概念有名字吗?如果不是,是因为它在某些方面存在缺陷,还是可以用更简单的部分构建?

Nou*_*are 8

您编写的类型签名基本上与以下内容相同:

traverse :: (Traversable t, Applicative f) => (a -> f b) -> t a -> f (t b)
Run Code Online (Sandbox Code Playgroud)

哪里f = m1t = m2.

m2但如果是任意单子,它并不总是有效。一定是Traversable

  • @jacobsa `Monad m =&gt; (a -&gt; b) -&gt; (a -&gt; mb)` 是 `(return .)`。 (2认同)