I want to automatically substitute the body of the function in the code.
For simple functions it seems to be easy enough, but I’d like to get the correct instance for those, which are attached to type class too (or an error, if there are multiple possible choices). Is it possible with the help of GHC API? At least, I’d like it to work in the cases where all class arguments are known.
Could you provide a (working) example of what you call “easy enough”? Otherwise, it’s not quite clear what you’re looking for.
I mean that for functions not inside a type class we can do this without typechecker: just go through all imports and find the function with this name. It’s not so easy for me, since I’m just strarting to use GHC API and have troubles on every step , but it doesn’t seems to be a real problem.
To make more clear what I want, here’s an example: in Data.Maybe
there’s a definition of function fromMaybe
. In my module I have something like
foo :: Maybe Int -> Int
foo = fromMaybe 0
I want to get the definition of fromMaybe
and substitute it here. Of course to do the latter I’ll need some more work, but I have some ideas how to do this. What I’m asking here is how can I do the former, i. e. getting the body of the function by it’s name. It seems to be not so hard to do in this case, but e. g. for
bar :: Int -> Int
bar = fromMaybe 0 . pure
it’s much trickier, since we need to know, from which instance should we take the definition of the pure
. However, I hope there should be something in typechecker output, that could be helpful for this.
There are some circumstances, in which we are not able to decide, which instance should we use, e. g. here we can’t substitute the fmap
definition:
baz :: Functor f => b -> f a -> f b
baz b = fmap (const b)
in these cases it’s perfectly well to say just “we unable to do this, please provide more information about what type f
is”.
It’s still not very clear to me what you want to achieve even without typeclasses. Do you mean you want to make GHC inline particular definitions? Or are you working on a compiler backend yourself? Or source-to-source transition? In other words, what output so you expect to get? A binary or surface Haskell?
Source-to-source translation (in Haskell). I’d like to make a tool for helping equational reasoning in Haskell. Surely I should have mentioned this in the initial question.
Oh, I see, thank you. I don’t know the answer to this question but I’d like to suggest some related work that may be of interest to you: LIquid Haskell’s suite for equational reasoning:
Of course, I know about liquid haskell. Thank’s for links anyway
HLS has a code action called unfold definition which inlines the right hand side of a definition at the use site. Maybe you can look at how they do that.
It seems that it can neither work with imports, nor with instances. However, I’ll have a look on how it works there, thank’s