我目前正在努力研究 monad。不幸的是,大多数关于该主题的文章都使用了 Haskell 而没有正确解释符号。然而,由于我主要使用 C++ 编程,所以我想在不学习新的编程语言的情况下理解 monads...
根据我在网上收集到的信息,一个 monad M
是类型 T
的类型构造函数,它至少提供了以下操作:
- 构建类型的实际方法
T
- 将任意类型转换为
T
的转换器(显然在 Haskell 中称为 return) - 用于应用存储在
T
中的值的组合器到函数f
(显然在 Haskell 中称为 bind)
将这些标准应用于 C++,在我看来 std::unique_ptr
可以被认为是一个单子(monad)。这是真的吗?
我的推理如下:
std::unique_ptr
模板用于构造实际类型 std::unique_ptr<T>
,因此:
- 类型构造函数是
std::unique_ptr<T>{}
或std::make_unique<T>()
- 再次,转换器将是构造函数或
std::make_unique
(有论据...) - 组合子可以是
std::bind(func, pointer.get())
,std::bind(func, *pointer)
或等效的 lambda
您是否同意,或者调用operator*()
/.get()
对于组合器取消资格 std::unique_ptr
从成为 monad?
我明白了,使用 std::unique_ptr
作为 monad 可能没有意义,因为它带有所有者语义。我只想知道它是否是一个。
最佳答案
Applying these criteria to C++, it seems to me that
std::unique_ptr
could be considered a monad. Is this true?
您的定义缺少 monad 法则,但我们可以看到 std::unique_ptr
(加上它是 bind
和 return
/unit
) 服从它们。
给定
template <typename T>
std::unique_ptr<T> unit(T t) { return std::make_unique<T>(t); }
template <typename T, typename U, typename F = std::function<std::unique_ptr<U>(T)>>
std::unique_ptr<U> bind(std::unique_ptr<T> ptr, F f) { return ptr ? f(*ptr) : nullptr; }
和表达式等价的概念 (≡
),即“这两个表达式产生相同的值”
我们需要
- 左恒等式:
bind(unit(a), f) ≡ f(a)
- 正确的身份:
bind(m, unit) ≡ m
- 关联性:
bind(bind(m, f), g) ≡ bind(m, [](auto x){ 返回绑定(bind)(f(x),g); })
I get, that using
std::unique_ptr
as a monad might not make sense because it carries owner semantic. I would just like to know, if it is one.
Monad 是应用语义的东西,例如 unique_ptr
的所有权,或 vector
的多重性,或 future
的异步性。 C++ 中有很多东西是单子(monad),但是(正如@NicolBolas 指出的那样)在单子(monad)结构上运行的东西并不多。
关于c++ - std::unique_ptr 可以被视为 monad 吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57150914/