Skip to content

Instantly share code, notes, and snippets.

@evincarofautumn
Created June 1, 2020 22:11
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save evincarofautumn/81e224590b6310af3c5c50e3d44a1df3 to your computer and use it in GitHub Desktop.
Save evincarofautumn/81e224590b6310af3c5c50e3d44a1df3 to your computer and use it in GitHub Desktop.
#include <iostream>
#include <optional>
#include <vector>
using namespace std;
template<template<typename A> typename F>
struct Alternative {
template<typename A>
static F<A> empty();
template<typename A>
static F<A> alt(F<A> &&, F<A> &&);
};
template<>
struct Alternative<std::optional> {
template<typename A>
static std::optional<A> empty() {
return std::nullopt;
}
template<typename A>
static std::optional<A> alt(std::optional<A> &&x, std::optional<A> &&y) {
return x.has_value() ? x : y;
}
};
template<template<typename A> typename F, typename A>
F<A> asum(std::vector<F<A>> fs) {
F<A> result;
for (auto &&f : fs) {
result = Alternative<F>::alt(std::move(result), std::move(f));
}
return result;
}
int main() {
std::vector<std::optional<int>> options {
std::nullopt,
std::make_optional(1),
std::make_optional(2),
};
std::cout << asum<std::optional, int>(options).value() << '\n';
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment