Monáda (funkcionální programování): Porovnání verzí

Smazaný obsah Přidaný obsah
mBez shrnutí editace
příklad v C++
Řádek 6:
 
Monády umožňují formulovat kód s vedlejšími efekty tak, aby byl referenčně transparentní, a tedy "čistý" (ve funkcionálním smyslu). Monády jsou zpravidla generické a jejich [[druh (teorie typů)|druh]] je <math>(* \rightarrow *) \rightarrow *</math>.
 
==Příklad==
 
[[Kontinuace]] v C++ lze reprezentovat následující třídou:
 
<source lang="cpp">
template<typename T> class Cont {
std::function<std::any(const std::function<std::any(T)>&)> fn;
public:
Cont(const decltype(fn)& f) : fn(f) {}
Cont(T&& x) : fn([x](auto f) { return f(x); }) {}
std::any operator()(const std::function<std::any(T)>& f) const { return fn(f); }
};
</source>
 
Aby byla '''Cont''' funktorem, musíme implementovat '''fmap''' nebo '''bind''':
 
<source lang="cpp">
template<template<typename> class M, typename T, typename U> struct Bind;
template<typename T, typename U> struct Bind<Cont,T,U> {
std::function<Cont<U>(T)> f;
auto operator()(const Cont<T>& m) {
return [this,m](auto g) {
return m([this,g](auto x) { return f(x)(g); });
};
}
};
</source>
 
C++ nemá typy vyšších [[druh]]ů, nicméně pomocí specializace šablon můžeme dosáhnout stejného efektu.
Konkrétně můžeme například definovat generické monadické operace '''fmap''' a '''join'''.
 
<source lang="cpp">
template<template<typename> class M, typename T, typename U> struct Fmap {
std::function<U(T)> f;
auto operator()(const M<T>&) const;
};
 
template<template<typename> class M, typename T> struct Join {
auto operator()(const M<M<T>>&) const;
};
 
template<template<typename> class M, typename T, typename U> auto Fmap<M,T,U>::operator()(const M<T>& m) const {
std::cerr << "generic fmap" << std::endl;
return Bind<M,T,U>{[&](auto x) { return M<U>{f(x)}; }}(m);
}
 
template<template<typename> class M, typename T> auto Join<M,T>::operator()(const M<M<T>>& m) const {
std::cerr << "generic join" << std::endl;
return Bind<M,M<T>,T>{[](M<T> x) { return x; }}(m);
}
</source>
 
Takto koncipovaný kód má tu výhodu, že poskytuje definice monadických funkcí bez ohledu na konkrétní typ. Proto stačí pro konkrétní monadický typ implementovat pouze buď '''bind''', nebo '''fmap''' a '''join''', podobně jako v čistě funkcionálních jazycích à la [[Haskell]].
 
== Externí odkazy ==