How to use raiseUnder2 - Polysemy

Welcome to the Functional Programming Zulip Chat Archive. You can join the chat here.

locallycompact

Hi, could someone explain how to use raiseUnder2/3. I'm trying to turn this into a reinterpreting version.

  -- | Cut a `Methodology` into two pieces at a midpoint.
  cutMethodology :: forall b c d r a.
                    Members '[ Methodology b c
                             , Methodology c d] r
                 => Sem (Methodology b d ': r) a
                 -> Sem r a
  cutMethodology = interpret \case
    Process b -> process @b @c b >>= process @c @d

So I do

cutMethodology' :: forall b c d r a.
                         Sem (Methodology b d ': r) a
                    -> Sem (Methodology b c ': Methodology c d ': r) a
cutMethodology' = raiseUnder2 >>> cutMethodology @b @c @d

But then I get

error:
    • Couldn't match ‘c’ with ‘b’
        arising from a use of ‘cutMethodology’
      ‘c’ is a rigid type variable bound by
        cutMethodology' :: forall b c d (r :: [(* -> *) -> * -> *]) a.
                             Sem (Methodology b d : r) a
                             -> Sem (Methodology b c : Methodology c d : r) a
        at /home/lc/Source/gitlab.com/homotopic-tech/flashblast/src/FlashBlast/Domain.hs:(51,1)-(53,72)
      ‘b’ is a rigid type variable bound by
        cutMethodology' :: forall b c d (r :: [(* -> *) -> * -> *]) a.
                             Sem (Methodology b d : r) a
                             -> Sem (Methodology b c : Methodology c d : r) a
        at /home/lc/Source/gitlab.com/homotopic-tech/flashblast/src/FlashBlast/Domain.hs:(51,1)-(53,72)
    • Known types:
        cutMethodology' :: Sem (Methodology b d : r) a
                           -> Sem (Methodology b c : Methodology c d : r) a
           -- /home/lc/Source/gitlab.com/homotopic-tech/flashblast/src/FlashBlast/Domain.hs:54:1
   |
54 | cutMethodology' = raiseUnder2 >>> cutMethodology @b @c @d

Shouldn't this work?

Georgi Lyubenov // googleson78

honestly kind of hard to debug for me without explicit code

Georgi Lyubenov // googleson78

did you try adding explicit types to everything?

Georgi Lyubenov // googleson78

also, try doing the eta expanded version, although it's probably not an issue here

locallycompact

It compiles successfully with concrete types.

cutMethodology' :: forall r a.
                           Sem (Methodology Text Int ': r) a
                        -> Sem (Methodology Text String ': Methodology String Int ': r) a
 cutMethodology' = raiseUnder2 >>> cutMethodology
Torsten Schmits

I'd guess it's enough to add type applications to raiseUnder2

Torsten Schmits

or maybe just use (.) instead of (>>>)

locallycompact

Mmm no combination of those work. Same error like this:

cutMethodology' :: forall b c d r a.
                           Sem (Methodology b d ': r) a
                      -> Sem (Methodology b c ': Methodology c d ': r) a
cutMethodology' f = f & raiseUnder2 @(Methodology b c) @(Methodology c d)
                        & cutMethodology @b @c @d
Torsten Schmits

if you do

let
  sem' :: Sem (Methodology b d : Methodology b c : Methodology c d : r) a
  sem' = raiseUnder2 sem

?

locallycompact

Like

  cutMethodology' :: forall b c d r a.
                           Sem (Methodology b d ': r) a
                      -> Sem (Methodology b c ': Methodology c d ': r) a
  cutMethodology' f =
    let
      sem' :: Sem (Methodology b d : Methodology b c : Methodology c d : r) a
      sem' = raiseUnder2 f
   in sem' & cutMethodology @b @c @d

Also same

Torsten Schmits

if you type-apply the r to cutMethodology?

locallycompact

Same

  cutMethodology' :: forall b c d r a.
                           Sem (Methodology b d ': r) a
                      -> Sem (Methodology b c ': Methodology c d ': r) a
  cutMethodology' f =
    let
      sem' :: Sem (Methodology b d : Methodology b c : Methodology c d : r) a
      sem' = raiseUnder2 f
 in sem' & cutMethodology @b @c @d @(Methodology b c ': Methodology c d ': r)
Torsten Schmits

does it work with reinterpret2?

Torsten Schmits

same as cutMethodology, but with the signature of cutMethodology'

Georgi Lyubenov // googleson78
bla :: forall b c d r a. Sem (Methodology b d : Methodology b c : Methodology c d : r) a -> Sem (Methodology b c : Methodology c d : r) a
bla = cutMethodology @b @c @d @(Methodology b c : Methodology c d : r)

this alone doesn't work either

Torsten Schmits

maybe it's the type family. if reinterpret2 doesn't work (or also if it does), try using two Member constraints.

Georgi Lyubenov // googleson78

highly doubt, the type family has enough information to fully evaluate

locallycompact

Two member constraints doesn't change

locallycompact

reinterpret2 is this right?

  cutMethodology'' :: forall b c d r a.
                           Sem (Methodology b d ': r) a
                      -> Sem (Methodology b c ': Methodology c d ': r) a
  cutMethodology'' = reinterpret2 \case
   Process b -> process @b @c b >>= process @c @d t

I get

    Ambiguous use of effect 'Methodology'
    ---
    Maybe-fix:
      add (Member (Methodology c d) (Methodology b c
                                       : Methodology c d : r)) to the context of
        the type signature
    If you already have the constraint you want, instead
      add a type application to specify
        'c', and 'd' directly, or activate polysemy-plugin which
          can usually infer the type correctly.
   |
64 |   Process b -> process @b @c b >>= process @c @d
Torsten Schmits

where's this "Maybe-fix" even coming from

Georgi Lyubenov // googleson78

https://github.com/ArturGajowy/ghc-clippy-plugin, ah this thing I guess, cool

A helpful companion to GHC. Overrides GHC messages, to the user's liking. - ArturGajowy/ghc-clippy-plugin
Georgi Lyubenov // googleson78

strangely, this works:

f :: forall a b c r. Member (Methodology b c) r => Sem (Methodology a b ': r) a -> Sem r a
f = undefined

bla2 :: Sem (Methodology a b ': Methodology b c ': r) a -> Sem (Methodology b c ': r) a
bla2 = f
Torsten Schmits

here there's no two Methodologys that have the same first type argument

Georgi Lyubenov // googleson78

smaller repro:

g :: (Member (Methodology a b) r, Member (Methodology b c) r) => Proxy (Methodology a c ': r) -> Proxy r
g = undefined

h :: forall a b c r. Proxy (Methodology a c : Methodology a b : Methodology b c : r) -> Proxy (Methodology a b : Methodology b c : r)
h = g
Georgi Lyubenov // googleson78
data Methodology' (sym :: Nat) a b

data Wrap1 a

data Wrap2 a

g :: (Member (Wrap1 (Methodology' n2 a b)) r, Member (Wrap2 (Methodology' n3 b c)) r) => Proxy ((Methodology' n1 a c) ': r) -> Proxy r
g = undefined

h :: Proxy ((Methodology' 0 a c) : Wrap1 (Methodology' 1 a b) : Wrap2 (Methodology' 2 b c) : r) -> Proxy (Wrap1 (Methodology' 1 a b) : Wrap2 (Methodology' 2 b c) : r)
h = g

this compiles

Georgi Lyubenov // googleson78

notably, it doesn't, if I remove the Nats, with an ungodly kind error

locallycompact

I think it's compiling without the Nats for me

locallycompact
data Methodology' a b

data Wrap0 a

data Wrap1 a

data Wrap2 a

g :: (Member (Wrap1 (Methodology' a b)) r, Member (Wrap2 (Methodology' b c)) r) => Proxy (W  rap0 (Methodology' a c) ': r) -> Proxy r typecheck:  Redundant constraints: (Member (Wrap1
g = undefined

h :: Proxy (Wrap0 (Methodology' a c) : Wrap1 (Methodology' a b) : Wrap2 (Methodology' b c)   : r) -> Proxy (Wrap1 (Methodology' a b) : Wrap2 (Methodology' b c) : r)
h = g
Georgi Lyubenov // googleson78
data Methodology' a b

data Wrap a

g :: (Member ((Methodology' a b)) r, Member (Wrap (Methodology' b c)) r) => Proxy ((Methodology' a c) ': r) -> Proxy r
g = undefined

h :: Proxy ((Methodology' a c) : (Methodology' a b) : Wrap (Methodology' b c) : r) -> Proxy ((Methodology' a b) : Wrap (Methodology' b c) : r)
h = g

further reduced

Georgi Lyubenov // googleson78

starting to look like a ghc bug/deficiency tbh

Georgi Lyubenov // googleson78

looks like the type class resolution method somehow decides that "yes, this is it, Methodology b _ must match Methodology b _", only later "realises" that the second class argument differ, resulting in an error

Georgi Lyubenov // googleson78

I'll try to further slim it down later

Torsten Schmits

does it work if you remove one type param of Methodology?

Georgi Lyubenov // googleson78

I don't know how to emulate the same situation with only one type param

locallycompact

Did you say that last one works for you or doesn't?

Georgi Lyubenov // googleson78

unless I forgot to save or something