Here is the diagram of Effect
provided in the official tutorial of pipes
package.
type Effect = Proxy X () () X
Upstream | Downstream
+---------+
| |
X <== <== ()
| |
() ==> ==> X
| | |
+----|----+
v
r
Since Effect
doesn't have any flow of data, I was expecting it to be just Proxy X X X X
, sealing all flows. But instead, it allows the two in-flows. Is there a particular reason for that? If I just write what a Effect
normally does, with signature Proxy X X X X
, it can pass the compiler perfectly fine:
myMonad :: Proxy X X X X IO ()
myMonad = do
a <- lift $ getLine
lift $ print a
return ()
Why can't we run
something like this?
You can run myMonad
from your example, by just taking the existing definition of runEffect
and generalizing its type somewhat:
import Pipes (lift)
import Pipes.Core (closed)
import Pipes.Internal
type Effect' a b = Proxy X a b X
-- Definition copied straight from Pipes.Core, type generalized to Effect'
runEffect' :: Monad m => Effect' a b m r -> m r
runEffect' = go
where
go p = case p of
Request v _ -> closed v
Respond v _ -> closed v
M m -> m >>= go
Pure r -> return r
eff :: Effect' X X IO ()
eff = do
a <- lift $ getLine
lift $ print a
return ()
main :: IO ()
main = runEffect' eff
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With