Hacker News new | past | comments | ask | show | jobs | submit login

> 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)

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact