:type
is not enough because the expression I want might include locally defined variables like things assigned with <-
, let
or where
. Typed holes (replacing the expression with _
and loading with ghc) are close, but they give you what's accepted there, which might be more general than the expression you're curious about.
I thought I found the jackpot with :type-at
, but I can't get it to work like I'd hope. With this file, named "thing.hs":
something :: ()
something = ()
main :: IO ()
main = return something
This is the result I get when using :type-at
:
> :set +c
> :l thing.hs
[1 of 1] Compiling Main ( thing.hs, interpreted )
Ok, one module loaded.
Collecting type info for 1 module(s) ...
> :type-at thing.hs 5 8 5 13 -- "return" on last line
<no location info>: error: not an expression: ‘’
> :type-at thing.hs 5 1 5 4 -- "main" on last line
:: IO ()
> :type-at thing.hs 5 15 5 23 -- "something" on last line
<no location info>: error: not an expression: ‘’
That's basically the same as using :type
. I was hoping I'd even be able to pass it the span for return something
and get Monad a => a ()
or IO ()
. Would be even cooler if one could select between seeing the type of the expression alone and the type of the expression "at that point" (after being restricted by the type that would appear with a type hole), but either would be fine.
When I try :type-at thing.hs 5 8 5 14
, I get :: () -> IO ()
. :type-at thing.hs 5 14 5 24
also works, as does :type-at thing.hs 5 14 6 1
.
So, the right bound should be the cell one past the end of the expression.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With