6
{-# LANGUAGE RebindableSyntax #-}
{-# LANGUAGE Arrows #-}

Given some constraint Foo, I would like to use the rebindable arrow do-notation in FooArrows: where types satisfy Foo. We can only lift arrows between Foo types and we can only tensor them using first if they are foo types.

class FooArrow hom where
  arr :: (Foo a) => (a -> b) -> hom a b
  (>>>) :: (Foo a, Foo b, Foo c) => hom a b -> hom b c -> hom a c
  first :: (Foo a, Foo b, Foo c) => hom a b -> hom (a, c) (b, c)

returnA :: (FooArrow hom, Foo a) => hom a a
returnA = arr (\a -> a)

And everything compiles fine until here. However, when actually using the notation, the compiler will complain that • Could not deduce (Foo b1) arising from a use of ‘first’, even in contexts where I think I have already provided all of the Foo constraints.

swap :: (FooArrow hom, Foo a, Foo b) => hom (a,b) (b,a)
swap = proc (a , b) ->
    returnA -< (b, a)

class Foo a where
instance Foo () where
instance (Foo a, Foo b) => Foo (a , b) where

Why am I getting this error? Am I missing something to make this work? Is it possible at all to get constrained arrow do-notation?

Mario Román
  • 600
  • 7
  • 12
  • Potentially related, although a different question: https://stackoverflow.com/questions/56620644/generalized-arrows-and-proc-notation – Mario Román Feb 21 '22 at 23:10
  • 1
    It was originally one of my aims with [constrained-categories](https://hackage.haskell.org/package/constrained-categories) to rebind arrow syntax, but I never actually got to that point – created the concepts of `Agent`s instead, which rather emulate Conal Elliott's _compiling to categories_ approach. – leftaroundabout Feb 22 '22 at 08:36

1 Answers1

5

Rebindable syntax for arrows is something that's been in feature-limbo for a long time. Indeed, the linked ticket details almost exactly your problem, and it's from 2013. I mean, technically, rebindable syntax for arrows exists, but as it says in the documentation: "the types of these functions must match the Prelude types very closely. Details are in flux; if you want to use this, ask!"

I feel obligated to point out that that 8 year-old ticket does have activity from a year and a half ago that says the work is in progress. But, if you need a solution now, I think the only way you can proceed with what you're trying to do is to use a GHC extension or pre-processor. Maybe Paterson's original arrowp pre-processor could work for your needs, but a search on hackage also reveals (the somewhat newer) arrowp-qq, which could be another option to look into.

DDub
  • 3,884
  • 1
  • 5
  • 12