c++ - std::unique_ptr 可以被视为 monad 吗?

标签 c++ functional-programming monads

我目前正在努力研究 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(加上它是 bindreturn/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/

相关文章:

C++ 模板 type_trait enable_if 类是映射

c++ - 如何在 C++ 中找到 ELF 二进制文件所需的动态库?

haskell - 为什么我在这里收到 "ambiguous type variable"错误?

Scala 使用模式匹配获取列表的第一个和最后一个元素

c# - 状态设计模式的功能等价物

haskell - 我怎样才能编写一个也可以进行错误处理的状态单子(monad)?

objective-c - 是否有用于 Objective-C 的 'andand' monad 版本?

c++ - 在 C++ 文件中声明全局类实例

c++ - std::atomic_flag 作为成员变量

haskell - 如何将一元函数作为带有灵活类型变量的参数传递?