4

I've been contributing for a past few weeks to a library that ports monads (mainly from mtl) to arrows.

Here's a quick example with the StateT monad from mtl:

newtype StateT s m a = StateT { runStateT :: s -> m (a, s) }
-- arrowization -->
newtype StateTA s a b c = StateTA { runStateTA :: a (b, s) (c, s) }

The "arrowizing" process wasn't really painful for most of the monads, but I can't figure out my arrow based on the Store comonad.

Every time I asked this question, people redirected me to the Cokleisli arrow, but will Cokleisli Store be equivalent to the arrow I'm looking for ?

The library being based on a mtl-style architecture (each arrow has a general class, like ArrowState, ArrowReader, etc...), I tried to figure out what will be the signatures of my functions in ArrowStore, but again, I can't.

I took a look at the arrows package which implements the same arrows as in the library I'm working on, but their CoState arrow (I heard CoState was another name for Store) defines no operations, so I guess the author also has troubles with this problem.

tl;dr:

  • Is Monad m => Kleisli m a b equivalent to the arrowized version m ?
  • Is it also true for comonads with the Cokleisli arrow ?
  • If so, how can I express the Store comonad as an arrow ?
  • If not, can we even "arrowize" comonads ?
baxbaxwalanuksiwe
  • 1,474
  • 10
  • 20
  • 1
    In short: _yes, the co-Kleisli category is what you want_. – leftaroundabout Oct 10 '16 at 15:36
  • @leftaroundabout: If it is equivalent, why didn't the authors of the `arrows` package just made types aliases ? (for arrow transformers I guess, but not sure) – baxbaxwalanuksiwe Oct 10 '16 at 15:39
  • 1
    Well, ask Ross Paterson... I don't know about the motivation for the `arrows` package specifically, but I think it's definitely interesting to _see_ how these special Kleisli arrows look in “direct form”, hence the desire to not just newtype a Kleisli. However, I think [`CoStateArrow`](http://hackage.haskell.org/package/arrows-0.4.4.1/docs/Control-Arrow-Transformer-CoState.html) is actually not quite right – this is a curried form with one base arrow replaced by a **Hask** one. I'd think it should be `a (s->b, s) c`. Or even actually `a (a s b, c)`. – leftaroundabout Oct 10 '16 at 15:52
  • 1
    I think if you want a good discussion on this topic you will have to give a better (read: formal) definition of 'arrowizing' - from the example it isn't clear precisely what you want. It doesn't seem to be the act of replacing arrows with type parameters of kind `* -> * -> *` , nor does it seem to refer to the fact that every arrow gives rise to a monad and v.v. ([WrappedMonad](https://hackage.haskell.org/package/base-4.9.0.0/docs/Control-Applicative.html#t:WrappedMonad), WrappedArrow, etc). – user2407038 Oct 10 '16 at 18:34

1 Answers1

5

Thanks to leftaroundabout's comment, I found the "arrowized" version of the Store comonad.

My problem was that I couldn't find the "direct form" - as leftaroundabout mentions it - of my arrow. But, if what I want is Cokleisli Store then the answer is straightforward (not very formal notation but you get the idea):

newtype CokleisliT a w b c = CokleisliT { runCokleisliT :: a (w b) c }
newtype Store s a = Store (s -> a, s)

    Arrow a => CokleisliT a (Store s) b c
<=> Arrow a => a (Store s b) c
<=> Arrow a => a (s -> b, s) c

From here, we can deduce the signatures of the ArrowStore class:

class Arrow a => ArrowStore s a | a -> s where
    pos   :: a () s
    peek  :: a () b -> a s b
    peeks :: a () b -> a (s -> s) b
    seek  :: a (s, b) c -> a b c
    seeks :: a (s, b) c -> a (s -> s, b) c

As for user's comment, apparently arrowizing a (co)monad is wrapping it in a (co)Kleisli arrow.

Here's the library for the other arrows: https://github.com/felko/atl.

Community
  • 1
  • 1
baxbaxwalanuksiwe
  • 1,474
  • 10
  • 20