Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Could std::unique_ptr be considered a monad?

I'm currently trying to wrap my head around monads. Unfortunately, most articles on the topic use Haskell without properly explaining the notation. Yet, as I am mainly programming in C++, I would like understand monads without learning a new programming language...

From what I gathered on the web, a monad M is a type constructor for a type T, which provides at least the following operations:

  • an actual way to construct the type T
  • a converter for converting an arbitrary type to T (apparently called return in Haskell)
  • a combinator for applying the value stored in T to a function f (apparently called bind in Haskell)

Applying these criteria to C++, it seems to me that std::unique_ptr could be considered a monad. Is this true?


My reasoning is as follows:

The std::unique_ptr template is used to construct the actual type std::unique_ptr<T>, thus:

  • the type constructor is either std::unique_ptr<T>{} or std::make_unique<T>()
  • the converter, again, would be the constructor or std::make_unique (with arguments...)
  • the combinator would be either std::bind(func, pointer.get()), std::bind(func, *pointer) or an equivalent lambda

Do you agree, or does the call to operator*()/.get() for the combinator disqualify std::unique_ptr from being a monad?


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.

like image 464
jan.sende Avatar asked Mar 03 '23 16:03

jan.sende


1 Answers

Applying these criteria to C++, it seems to me that std::unique_ptr could be considered a monad. Is this true?

Your definition is missing the monad laws, but we can see that there is appropriate formulation by which std::unique_ptr (plus it's bind and return/unit) obeys them.

Given

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; }

and a notion of expression equivalence (), i.e. "these two expressions result in the same value"

We require

  • Left identity: bind(unit(a), f) ≡ f(a)
  • Right identity: bind(m, unit) ≡ m
  • Associativity: bind(bind(m, f), g) ≡ bind(m, [](auto x){ return 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.

A monad is something that applies a semantic, like unique_ptr's ownership, or vectors multiplicity, or future's asynchronicity. There are lots of things in C++ that are monads, but (as @NicolBolas notes) there isn't much that operates on the monadic structure.

like image 197
Caleth Avatar answered Mar 12 '23 04:03

Caleth