Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rewriting to add constraints? #37

Open
isovector opened this issue Sep 1, 2021 · 6 comments
Open

Rewriting to add constraints? #37

isovector opened this issue Sep 1, 2021 · 6 comments

Comments

@isovector
Copy link

isovector commented Sep 1, 2021

Hi all,

I've got a big refactoring project coming up, and am wondering if retrie can help me. I'd like to change the following signature:

foo :: Sem r ()

to instead be:

foo :: Member (Embed IO) r => Sem r ()

and then push the Member (Embed IO) r constraint through all transitive callsites to foo. None of the documentation seems to suggests anything about this use case --- can retrie handle it?

@pepeiborra
Copy link
Contributor

pepeiborra commented Sep 1, 2021

That would be sweet, but I don't think retrie is able to rewrite types.

EDIT: I was wrong, see --adhoc-type

@pepeiborra
Copy link
Contributor

You can hack something that traverses the hie file, looking for occurrences of foo with the type Sem r () and then uses SYB + ghc-exactprint to rewrite it.

processFile :: DynFlags -> HieFile -> IO ()
processFile dflags HieFile{..} =
  forM_ (getAsts hie_asts) $ \root ->
    forM_ (flattenAst root) $ \Node{..} -> do
      let NodeInfo{..} = nodeInfo
      case Map.toList nodeIdentifiers of
        [(Right name, IdentifierDetails{..})]
          | (ty:_) <- nodeType
          , Just _ <- identType
          , [Use] <- Set.toList identInfo ->
             processName dflags nodeSpan name $ recoverFullType ty hie_types
        _ -> return ()

processName :: DynFlags -> Span -> Name -> HieTypeFix -> IO ()
processName dflags loc name ty = ... pattern match and use SYB and ghc-exactprint ...

I wonder if this could be generalised and incorporated in retrie somehow

@isovector
Copy link
Author

Would such a thing do transitive dependencies? Like, anything that calls anything that calls foo also needs an updated type signature.

I think I'll probably just play whack-a-mole in HLS on this one. Add constraint is pretty fantastic!

@TristanCacqueray
Copy link

Without touching the callsite, would it be possible to use retrie for changing:

bar :: a -> IO b

... into:

bar :: MonadIO m => a -> m b

It seems like retrie --adhoc-type 'IO b = MonadIO m => m b' produces bar :: a -> (MonadIO m => m b)
but a -> IO b = MonadIO m => a -> m b fails with Malformed head of type or class declaration: a -> IO b
or Fn a (IO b) = ... fails with Unexpected type ‘IO b’.

Am I missing something, or is it currently not possible to add contraints on multi argument function?

@pepeiborra
Copy link
Contributor

pepeiborra commented Oct 6, 2021

Can you run a second adhoc-type rewrite to fix the malformed signatures? --adhoc-type 'a -> (MonadIO m => m b) = MonadIO m => a -> m b

@TristanCacqueray
Copy link

@pepeiborra unfortunately this fails with this message:

["type a -> (MonadIO m => m b) = MonadIO m => a -> m b"]

parseAdhocTypes:1:6: error:
    Malformed head of type or class declaration: a -> (MonadIO m => m b)
retrie: user error (parse failed)

Similarly, trying Fn a (MonadIO m => m b) = ... results in Unexpected type ‘MonadIO m => m b’

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants