typeclasspurescriptprofunctor

Why is defining an instance of Choice failing with unknown value?


UPDATE: I'm inlining the code here instead.

I'm trying to define an instance of Data.Profunctor.Choice where right is defined by calling left, but for some reason the compiler complains that left is unknown.

newtype StateTrans s i o = ST (Tuple s i → Tuple s o)

instance stFunctor ∷ Functor (StateTrans s a) where
  map f (ST st) = ST $ second f <<< st

instance stProfunctor ∷ Profunctor (StateTrans s) where
  dimap f g (ST st) = ST $ second g <<< st <<< second f

instance stChoice ∷ Choice (StateTrans s) where
  left (ST f) = ST lf
    where
    lf (Tuple s (Left a)) = let (Tuple s' b) = f (Tuple s a)
                            in Tuple s' (Left b)
    lf (Tuple s (Right c)) = Tuple s (Right c)
  -- Fails to compile with: Unknown value left
  right f = arr mirror <<< left f <<< arr mirror
    where
    mirror Left x = Right x
    mirror Right x = Left x

Probably a silly mistake but I've been looking at my code for so long, I can't figure out what's wrong.

(Of minor importance and unrelated: in the Right case for left, I have to unwrap and repackage the value so that it type-aligns. Adding a type ascription fails to compile too.)

Strangely enough, I have no problem doing the same for Strong, see:

instance stStrong ∷ Strong (StateTrans s) where
  first (ST f) = ST ff
    where
    ff (Tuple s (Tuple a c)) = let (Tuple s' b) = f $ Tuple s a
                               in Tuple s' (Tuple b c)
  second f = arr swap <<< first f <<< arr swap

Solution

  • I'm not 100% sure as the pasted snippet doesn't include imports, but I suspect you have an import for Data.Profunctor.Choice (class Choice) rather than Data.Profunctor.Choice (class Choice, left, right).

    Importing a class does not import its members implicitly, even though it is possible to define them in an instance without doing so.