por fin entiendo qué son las mónadas - using std::cpp · por fin entiendo qué son las mónadas ....
TRANSCRIPT
![Page 1: Por fin entiendo qué son las mónadas - using std::cpp · Por fin entiendo qué son las mónadas . ... Por cierto, esta mónada es comúnmente conocida como Maybe Monad Un poco de](https://reader034.vdocument.in/reader034/viewer/2022051410/602e1ad2c40ab41e8802b75c/html5/thumbnails/1.jpg)
Telefónica Digital – Video Products Definition & Strategy
using std::cpp 2014
Joaquín Mª López Muñoz <[email protected]> Madrid, octubre 2014
Por fin entiendo qué son las mónadas
![Page 2: Por fin entiendo qué son las mónadas - using std::cpp · Por fin entiendo qué son las mónadas . ... Por cierto, esta mónada es comúnmente conocida como Maybe Monad Un poco de](https://reader034.vdocument.in/reader034/viewer/2022051410/602e1ad2c40ab41e8802b75c/html5/thumbnails/2.jpg)
No es esto…
![Page 3: Por fin entiendo qué son las mónadas - using std::cpp · Por fin entiendo qué son las mónadas . ... Por cierto, esta mónada es comúnmente conocida como Maybe Monad Un poco de](https://reader034.vdocument.in/reader034/viewer/2022051410/602e1ad2c40ab41e8802b75c/html5/thumbnails/3.jpg)
Tampoco esto…
![Page 4: Por fin entiendo qué son las mónadas - using std::cpp · Por fin entiendo qué son las mónadas . ... Por cierto, esta mónada es comúnmente conocida como Maybe Monad Un poco de](https://reader034.vdocument.in/reader034/viewer/2022051410/602e1ad2c40ab41e8802b75c/html5/thumbnails/4.jpg)
¡Son las mónadas!
![Page 5: Por fin entiendo qué son las mónadas - using std::cpp · Por fin entiendo qué son las mónadas . ... Por cierto, esta mónada es comúnmente conocida como Maybe Monad Un poco de](https://reader034.vdocument.in/reader034/viewer/2022051410/602e1ad2c40ab41e8802b75c/html5/thumbnails/5.jpg)
Definición formal
![Page 6: Por fin entiendo qué son las mónadas - using std::cpp · Por fin entiendo qué son las mónadas . ... Por cierto, esta mónada es comúnmente conocida como Maybe Monad Un poco de](https://reader034.vdocument.in/reader034/viewer/2022051410/602e1ad2c40ab41e8802b75c/html5/thumbnails/6.jpg)
Definición formal
![Page 7: Por fin entiendo qué son las mónadas - using std::cpp · Por fin entiendo qué son las mónadas . ... Por cierto, esta mónada es comúnmente conocida como Maybe Monad Un poco de](https://reader034.vdocument.in/reader034/viewer/2022051410/602e1ad2c40ab41e8802b75c/html5/thumbnails/7.jpg)
Pero, ¿qué es realmente una mónada?
Una cinta transportadora
Un overload del operador “;”
Una unidad de computación
Un truco para introducir efectos
laterales en programación
funcional
Un objeto cuyos métodos
devuelven mónadas
No es posible definir qué es una mónada
Algo parecido a un escritorio
Una forma de componer funciones
![Page 8: Por fin entiendo qué son las mónadas - using std::cpp · Por fin entiendo qué son las mónadas . ... Por cierto, esta mónada es comúnmente conocida como Maybe Monad Un poco de](https://reader034.vdocument.in/reader034/viewer/2022051410/602e1ad2c40ab41e8802b75c/html5/thumbnails/8.jpg)
Construyamos una mónada en C++
![Page 9: Por fin entiendo qué son las mónadas - using std::cpp · Por fin entiendo qué son las mónadas . ... Por cierto, esta mónada es comúnmente conocida como Maybe Monad Un poco de](https://reader034.vdocument.in/reader034/viewer/2022051410/602e1ad2c40ab41e8802b75c/html5/thumbnails/9.jpg)
optional<T>
template<typename T> struct optional { optional(T const& x) optional(none_t); T const& get()const; T& get(); operator bool()const; // not really }; optional<double> inv(double x){ if(x==0.0)return none; else return 1.0/x; } optional<double> sqr(double x){ if(x<0.0)return none; else return std::sqrt(x); } optional<double> arcsin(double x){ if(x<-1.0||x>1.0)return none; else return std::asin(x); }
![Page 10: Por fin entiendo qué son las mónadas - using std::cpp · Por fin entiendo qué son las mónadas . ... Por cierto, esta mónada es comúnmente conocida como Maybe Monad Un poco de](https://reader034.vdocument.in/reader034/viewer/2022051410/602e1ad2c40ab41e8802b75c/html5/thumbnails/10.jpg)
Calcular…
La composición directa de funciones no compila optional<double> f(double x) { return inv(arcsin(sqr(x)); } main.cpp: In function 'boost::optional<double> f(double)': main.cpp:34:27: error: cannot convert 'boost::optional<double>' to 'double' for argument '1' to 'boost::optional<double> arcsin(double)' return inv(arcsin(sqr(x)); ^
arcsin acepta doubles, no optional<double>s
Semántica deseada: none_t aborta la computación
𝒇 𝒙 =𝟏
arcsin( 𝒙)
![Page 11: Por fin entiendo qué son las mónadas - using std::cpp · Por fin entiendo qué son las mónadas . ... Por cierto, esta mónada es comúnmente conocida como Maybe Monad Un poco de](https://reader034.vdocument.in/reader034/viewer/2022051410/602e1ad2c40ab41e8802b75c/html5/thumbnails/11.jpg)
Ahora sí
optional<double> f(double x) { auto y=sqr(x); auto z=y?arcsin(y.get()):none; auto w=z?inv(z.get()):none; return w; }
¿Detectas un patrón aquí?
![Page 12: Por fin entiendo qué son las mónadas - using std::cpp · Por fin entiendo qué son las mónadas . ... Por cierto, esta mónada es comúnmente conocida como Maybe Monad Un poco de](https://reader034.vdocument.in/reader034/viewer/2022051410/602e1ad2c40ab41e8802b75c/html5/thumbnails/12.jpg)
Hagámoslo genérico
template<typename T,typename F> auto operator>>=(const optional<T>& x,F&& f) { return x?f(x.get()):none; } optional<double> f(double x) { return (sqr(x)>>=arcsin)>>=inv; }
No hay nada especial en la elección de “>>=”
En C++, de hecho, no es muy buena elección
Léase bind (tampoco muy afortunado en C++)
![Page 13: Por fin entiendo qué son las mónadas - using std::cpp · Por fin entiendo qué son las mónadas . ... Por cierto, esta mónada es comúnmente conocida como Maybe Monad Un poco de](https://reader034.vdocument.in/reader034/viewer/2022051410/602e1ad2c40ab41e8802b75c/html5/thumbnails/13.jpg)
optional<double> f(double x) { return inv(arcsin(sqr(x)); } optional<double> f(double x) { return (sqr(x)>>=arcsin)>>=inv; }
>>= es un adaptador activo
x arcsin inv
>>= sqr x
arcsin
>>=
inv
sqr
![Page 14: Por fin entiendo qué son las mónadas - using std::cpp · Por fin entiendo qué son las mónadas . ... Por cierto, esta mónada es comúnmente conocida como Maybe Monad Un poco de](https://reader034.vdocument.in/reader034/viewer/2022051410/602e1ad2c40ab41e8802b75c/html5/thumbnails/14.jpg)
optional<double> f(double x) { return ((optional<double>(x)>>=sqr)>>=arcsin)>>=inv; }
unit acepta un objeto x y devuelve la mónada asociada a x
También se lo llama return (confuso en C++)
En este ejemplo unit(x) ~ optional<double>(x)
Un poco de Lego
>>= x
arcsin
>>=
inv
>>=
sqr
unit
![Page 15: Por fin entiendo qué son las mónadas - using std::cpp · Por fin entiendo qué son las mónadas . ... Por cierto, esta mónada es comúnmente conocida como Maybe Monad Un poco de](https://reader034.vdocument.in/reader034/viewer/2022051410/602e1ad2c40ab41e8802b75c/html5/thumbnails/15.jpg)
optional<double> f(double x) { auto g=[](double y){return arcsin(y)>>=inv;}; return sqr(x)>>=g; }
bind es “asociativo”
Un poco de Lego
>>= sqr x
arcsin
inv
>>=
![Page 16: Por fin entiendo qué son las mónadas - using std::cpp · Por fin entiendo qué son las mónadas . ... Por cierto, esta mónada es comúnmente conocida como Maybe Monad Un poco de](https://reader034.vdocument.in/reader034/viewer/2022051410/602e1ad2c40ab41e8802b75c/html5/thumbnails/16.jpg)
optional<double> f(double x) { auto minv=[](const optional<double>& y){return y>>=inv;}; auto marcsin=[](const optional<double>& y){return y>>=arcsin;}; auto msqr=[](const optional<double>& y){return y>>=sqr;}; return minv(marcsin(msqr(optional<double>(x)))); }
Por cierto, esta mónada es comúnmente conocida como Maybe Monad
Un poco de Lego
sqr
>>=
arcsin
>>=
inv
>>=
x unit
![Page 17: Por fin entiendo qué son las mónadas - using std::cpp · Por fin entiendo qué son las mónadas . ... Por cierto, esta mónada es comúnmente conocida como Maybe Monad Un poco de](https://reader034.vdocument.in/reader034/viewer/2022051410/602e1ad2c40ab41e8802b75c/html5/thumbnails/17.jpg)
Las leyes de la mónada
unit : T M<T>
>>= : (M<T>, T M<T’>) M<T’>
unit(x) >>= f ≡ f(x)
m >>= unit ≡ m
(m >>= f) >>= g ≡ m >>= λx.(f(x) >>= g)
![Page 18: Por fin entiendo qué son las mónadas - using std::cpp · Por fin entiendo qué son las mónadas . ... Por cierto, esta mónada es comúnmente conocida como Maybe Monad Un poco de](https://reader034.vdocument.in/reader034/viewer/2022051410/602e1ad2c40ab41e8802b75c/html5/thumbnails/18.jpg)
¿Qué es una mónada? Mi modesto intento de definición
![Page 19: Por fin entiendo qué son las mónadas - using std::cpp · Por fin entiendo qué son las mónadas . ... Por cierto, esta mónada es comúnmente conocida como Maybe Monad Un poco de](https://reader034.vdocument.in/reader034/viewer/2022051410/602e1ad2c40ab41e8802b75c/html5/thumbnails/19.jpg)
Una mónada es un patrón de diseño que permite componer funciones con tipos de retorno extendidos
Un tipo extendido contiene 0 ó más valores de un tipo básico más cierta semántica/información asociada
¿Qué es una mónada? Mi modesto intento de definición
![Page 20: Por fin entiendo qué son las mónadas - using std::cpp · Por fin entiendo qué son las mónadas . ... Por cierto, esta mónada es comúnmente conocida como Maybe Monad Un poco de](https://reader034.vdocument.in/reader034/viewer/2022051410/602e1ad2c40ab41e8802b75c/html5/thumbnails/20.jpg)
template<typename T> class histogram { public: histogram(){} histogram(const T& x); // our unit ctor, later on const_iterator begin()const; const_iterator end()const; void add(const T& x,double f); }; histogram<int> dice(int n) { histogram<int> res; for(int i=1;i<=n;++i)res.add(i,1.0/n); return res; } int main() { std::cout<<dice(6); }
Algo más complicado: histogramas
1 ******************** 2 ******************** 3 ******************** 4 ******************** 5 ******************** 6 ********************
![Page 21: Por fin entiendo qué son las mónadas - using std::cpp · Por fin entiendo qué son las mónadas . ... Por cierto, esta mónada es comúnmente conocida como Maybe Monad Un poco de](https://reader034.vdocument.in/reader034/viewer/2022051410/602e1ad2c40ab41e8802b75c/html5/thumbnails/21.jpg)
Composición de histogramas ~ probabilidad condicionada
1
0.2
2
0.4
3
0.4
A
0.2
B
0.3
C
0.5
A
0.0
B
0.6
C
0.4
A
0.25
B
0.5
C
0.25
A
0.14
B
0.5
C
0.36
![Page 22: Por fin entiendo qué son las mónadas - using std::cpp · Por fin entiendo qué son las mónadas . ... Por cierto, esta mónada es comúnmente conocida como Maybe Monad Un poco de](https://reader034.vdocument.in/reader034/viewer/2022051410/602e1ad2c40ab41e8802b75c/html5/thumbnails/22.jpg)
template<typename T,typename F> auto operator>>=(const histogram<T>& x,F&& f) { decltype(f(x.begin()->first)) res; for(const auto& p:x){ for(const auto& q:f(p.first)){ res.add(q.first,q.second*p.second); } } return res; } int main() { auto h=dice(6)>>=dice; std::cout<<h; }
Estrictamente hablando, histogram<T> es una mónada
restringida
Composición de histogramas ~ >>=
1 ************************************************* 2 **************************** 3 ******************* 4 ************ 5 ******* 6 ***
![Page 23: Por fin entiendo qué son las mónadas - using std::cpp · Por fin entiendo qué son las mónadas . ... Por cierto, esta mónada es comúnmente conocida como Maybe Monad Un poco de](https://reader034.vdocument.in/reader034/viewer/2022051410/602e1ad2c40ab41e8802b75c/html5/thumbnails/23.jpg)
int main() { auto h1=dice(6); auto h2=dice(4); auto h3= h1>>=[&](int x){ return h2>>=[&](int y){ return histogram<int>(x+y); }; }; std::cout<<h3; }
En Haskell, este constructo se implementa con la notación do do x <- dice 6 y <- dice 4 return x+y
No tan relevante en un lenguaje imperativo como C++ (por ahora)
Pero hay otro concepto más interesante aquí…
Suma de experimentos
2 ***** 3 ********** 4 *************** 5 ******************** 6 ******************** 7 ******************** 8 *************** 9 ********** 10 *****
![Page 24: Por fin entiendo qué son las mónadas - using std::cpp · Por fin entiendo qué son las mónadas . ... Por cierto, esta mónada es comúnmente conocida como Maybe Monad Un poco de](https://reader034.vdocument.in/reader034/viewer/2022051410/602e1ad2c40ab41e8802b75c/html5/thumbnails/24.jpg)
Lifting monádico
![Page 25: Por fin entiendo qué son las mónadas - using std::cpp · Por fin entiendo qué son las mónadas . ... Por cierto, esta mónada es comúnmente conocida como Maybe Monad Un poco de](https://reader034.vdocument.in/reader034/viewer/2022051410/602e1ad2c40ab41e8802b75c/html5/thumbnails/25.jpg)
f(T1, … ,Tn) R F(M<T1>, … , M<Tn>) M<R> template<template<typename> class M,typename T1,typename T2> auto operator+(const M<T1>& m1,const M<T2>& m2) { return m1>>=[&](const T1& x){ return m2>>=[&](const T2& y){ return M<decltype(x+y)>(x+y); }; }; } int main() { auto h1=dice(6); auto h2=dice(4); auto h3=h1+h2; std::cout<<h3; std::cout<<"--------------------------\n"; std::cout<<optional<int>(4)+optional<int>(3)<<"\n"; std::cout<<optional<int>(4)+optional<int>(none)<<"\n"; }
Lifting monádico
2 ***** 3 ********** 4 *************** 5 ******************** 6 ******************** 7 ******************** 8 *************** 9 ********** 10 ***** -------------------------- 7 none
![Page 26: Por fin entiendo qué son las mónadas - using std::cpp · Por fin entiendo qué son las mónadas . ... Por cierto, esta mónada es comúnmente conocida como Maybe Monad Un poco de](https://reader034.vdocument.in/reader034/viewer/2022051410/602e1ad2c40ab41e8802b75c/html5/thumbnails/26.jpg)
Intersección de líneas captura / closure
Lifting monádico con argumentos variádicos: http://tinyurl.com/mlifting
La implementación no es trivial
Diagrama de flujo
>>=
+ unit
m2
>>= m1
![Page 27: Por fin entiendo qué son las mónadas - using std::cpp · Por fin entiendo qué son las mónadas . ... Por cierto, esta mónada es comúnmente conocida como Maybe Monad Un poco de](https://reader034.vdocument.in/reader034/viewer/2022051410/602e1ad2c40ab41e8802b75c/html5/thumbnails/27.jpg)
Un catálogo de mónadas
![Page 28: Por fin entiendo qué son las mónadas - using std::cpp · Por fin entiendo qué son las mónadas . ... Por cierto, esta mónada es comúnmente conocida como Maybe Monad Un poco de](https://reader034.vdocument.in/reader034/viewer/2022051410/602e1ad2c40ab41e8802b75c/html5/thumbnails/28.jpg)
Un catálogo de mónadas
Maybe
List
I/O
State
Reader
Writer
Continuation
![Page 29: Por fin entiendo qué son las mónadas - using std::cpp · Por fin entiendo qué son las mónadas . ... Por cierto, esta mónada es comúnmente conocida como Maybe Monad Un poco de](https://reader034.vdocument.in/reader034/viewer/2022051410/602e1ad2c40ab41e8802b75c/html5/thumbnails/29.jpg)
Continuation Monad (muy por encima)
![Page 30: Por fin entiendo qué son las mónadas - using std::cpp · Por fin entiendo qué son las mónadas . ... Por cierto, esta mónada es comúnmente conocida como Maybe Monad Un poco de](https://reader034.vdocument.in/reader034/viewer/2022051410/602e1ad2c40ab41e8802b75c/html5/thumbnails/30.jpg)
Construcción de un hilo
template<typename T,typename R> struct yarn { yarn(const T& x); template<typename F> // F: T->T2 yarn<T2,R> then(F f)const; R run(); }; int str_size(const std::string& str); int times_10(int x); std::string to_str (int x); int main() { auto c1=yarn<std::string,int>("hello"). then(str_size). then(times_10). then(to_str). then(str_size); std::cout<<"running...\n"; std::cout<<c1.run()<<"\n"; }
![Page 31: Por fin entiendo qué son las mónadas - using std::cpp · Por fin entiendo qué son las mónadas . ... Por cierto, esta mónada es comúnmente conocida como Maybe Monad Un poco de](https://reader034.vdocument.in/reader034/viewer/2022051410/602e1ad2c40ab41e8802b75c/html5/thumbnails/31.jpg)
str_size, times_10, to_str no devuelven valores monádicos
De hecho, then se implementa en función de >>=
¿Tanto lío para llamar unas cuantas funciones una tras otra?
El esquema es familiar, ¿no?
then hello then then
times_10 str_size to_str
then
str_size
then >>=
f f
yarn
yarn
![Page 32: Por fin entiendo qué son las mónadas - using std::cpp · Por fin entiendo qué son las mónadas . ... Por cierto, esta mónada es comúnmente conocida como Maybe Monad Un poco de](https://reader034.vdocument.in/reader034/viewer/2022051410/602e1ad2c40ab41e8802b75c/html5/thumbnails/32.jpg)
Unas notas antes de partir
![Page 33: Por fin entiendo qué son las mónadas - using std::cpp · Por fin entiendo qué son las mónadas . ... Por cierto, esta mónada es comúnmente conocida como Maybe Monad Un poco de](https://reader034.vdocument.in/reader034/viewer/2022051410/602e1ad2c40ab41e8802b75c/html5/thumbnails/33.jpg)
Unas notas antes de partir
Es posible entender las mónadas
¡Veo mónadas por todas partes!
Patrón de diseño para la composición de funciones extendidas
Haskell: mónadas + do estilo imperativo
C++: inversión de control, entornos no imperativos
Lifting remplazamiento de valores básicos por valores monádicos
Louis, creo que esto puede ser el comienzo de una bella amistad
![Page 34: Por fin entiendo qué son las mónadas - using std::cpp · Por fin entiendo qué son las mónadas . ... Por cierto, esta mónada es comúnmente conocida como Maybe Monad Un poco de](https://reader034.vdocument.in/reader034/viewer/2022051410/602e1ad2c40ab41e8802b75c/html5/thumbnails/34.jpg)
Por fin entiendo qué son las mónadas
Gracias
github.com/joaquintides/usingstdcpp2014
using std::cpp 2014
Joaquín Mª López Muñoz <[email protected]> Madrid, octubre 2014