我正在用 C++ 编写一些相对函数式的代码,并试图避免为它发明一个坏名字。为此,我试图尽可能在 Haskell 中使用同构概念的名称。 (需要说明的是,我对 Haskell 了解不多,但阅读有关它的内容非常有启发性。)
如果我正确地完成了 Haskell 输入,我相信我正在寻找名称的概念会有这个签名:
someName :: (Monad m1, Monad m2) => (a -> m1 b) -> (m2 a -> m1 m2 b)
这个想法是你有一个适合用来绑定(bind) m1
类型的 monad 的函数,然后你将它转换成一个适合绑定(bind) m1
值的函数包含 m2
值。
我写的 Haskell 写得不够好,无法举个例子,但这里是伪 C++ 说明我想要什么,使用 std::optional
和 absl::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)));
这个概念有名字吗?如果没有,是因为它在某些方面存在缺陷,还是可以用更简单的部分构建?
最佳答案
你写的类型签名基本一样:
traverse :: (Traversable t, Applicative f) => (a -> f b) -> t a -> f (t b)
其中 f = m1
和 t = m2
。
但如果 m2
是任意 monad,它并不总是有效。必须是 Traversable
.
关于haskell - 这个概念在 Haskell 中叫什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/74286532/