3 ms·
BIO: A Simple Streaming Abstraction
- Twisol 5y ago> The result is a type focusing on callback transformation: > type BIO inp out = (Maybe out -> IO ()) -> Maybe inp -> IO () Huh, neat! Looks like profunctor optics to me. ("Callback transformation" is a really good way to think about profunctor optics, honestly. The "profunctor" part describes the kind of callback you're transforming.) Generalize slightly: type (:>>:) s t = Maybe s -> IO t type BIO' s t a b = (s :>>: t) -> (a :>>: b) type BIO inp out = BIO' out () inp () Tweaked just a bit further, to highlight the similarity with general profunctor optics: type BIO' s t a b = (Profunctor p, p ~ (:>>:)) => p s t -> p a b That is, BIO' is the type of optics that only work specifically for the profunctor :>>:. (As it happens, `f a -> g b` is a profunctor for any pair of functors `f` and `g`.) With either representation, you should be able to compose BIO transformations with general prisms and get BIO transformations back. (Lenses are out; I don't think you can implement `Strong` for `:>>:`.) instance Choice (:>>:) where -- left' :: (Maybe a -> IO b) -> (Maybe (Either a c) -> IO (Either b c)) left' :: (a :>>: b) -> ((Either a c) :>>: (Either b c)) left' f Nothing = fmap Left (f Nothing) left' f (Just (Left a)) = fmap Left (f (Just a)) left' f (Just (Right c)) = fmap Right (return c)