retrie
retrie copied to clipboard
Rewriting to add constraints?
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?
That would be sweet, but I don't think retrie is able to rewrite types.
EDIT: I was wrong, see --adhoc-type
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
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!
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?
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
@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’