/pr/ – programming
@abcd32d50c984769b93b47826ff5ca90
fulmar
2023-04-30 09:00:37
Let's say you have a data structure. And you see that you can implement functions return and bind for it in some way. So it is a monad. But you see different useful ways of implementing these functions. What you can do is to encode these functions in some data structure like an abstract syntax tree and then write different interpreters for it.
Let's try to encode the functions using a data structure:
For any ma :: m a we can do:
bind ma return :: m a
And the result will be equal to ma. So it gives us a hint how to convert any value ma to the data structure above.
Let's replace the functions by expressions:
Bind ma Return :: Expr m a
For this to work, we see that we need to change the type of Bind to this:
Bind :: (m b) -> (b -> Expr m a) -> Expr m a
So we get:
Congratulations! We've just invited a "freer monad". Expr m is that shit.
Let's continue thinking.
Function bind can be defined using fmap and join:
bind mb f = join (fmap f mb)
This means that if m is a functor, i.e. function fmap is defined for it, and we have data Bind mb f, we can calculate fmap f mb before giving any interpretation of Bind. So we can store the result of fmap f mb :: (m (Expr m a)) instead of storing mb and f and doing nothing with them. Therefore we can change the type of Bind to this:
Bind :: (m (Expr m a)) -> Expr m a
We get:
Congratulations! We've just invited a "free monad". This version of Expr m is that shit.
Let's try to encode the functions using a data structure:
data Expr m a where
Return :: a -> Expr m a
Bind :: (m b) -> (b -> m a) -> Expr m a
For any ma :: m a we can do:
bind ma return :: m a
And the result will be equal to ma. So it gives us a hint how to convert any value ma to the data structure above.
Let's replace the functions by expressions:
Bind ma Return :: Expr m a
For this to work, we see that we need to change the type of Bind to this:
Bind :: (m b) -> (b -> Expr m a) -> Expr m a
So we get:
data Expr m a where
Return :: a -> Expr m a
Bind :: (m b) -> (b -> Expr m a) -> Expr m a
Congratulations! We've just invited a "freer monad". Expr m is that shit.
Let's continue thinking.
Function bind can be defined using fmap and join:
bind mb f = join (fmap f mb)
This means that if m is a functor, i.e. function fmap is defined for it, and we have data Bind mb f, we can calculate fmap f mb before giving any interpretation of Bind. So we can store the result of fmap f mb :: (m (Expr m a)) instead of storing mb and f and doing nothing with them. Therefore we can change the type of Bind to this:
Bind :: (m (Expr m a)) -> Expr m a
We get:
data Expr m a where
Return :: a -> Expr m a
Bind :: (m (Expr m a)) -> Expr m a
Congratulations! We've just invited a "free monad". This version of Expr m is that shit.
@358be0b199de416990fa58f6841ab7f4
fulmar
2023-04-30 09:06:09
*invented блядь, ебаный т9
Решил на своём ломаном английском написать зачем-то.
Решил на своём ломаном английском написать зачем-то.