简体   繁体   中英

How can I set up Haskell's GHCI to interactively evaluate functions to their signature (type) instead of getting errors?

To see the function's signature in Haskell GHCI, I have to prefix it with :t :

Prelude> f = \x -> x+1
Prelude> :t f
f :: Num a => a -> a

But typing that prefix every time grows quickly old. If I leave it out, I get error:

Prelude> f

<interactive>:5:1: error:
• No instance for (Show (a0 -> a0)) arising from a use of ‘print’
    (maybe you haven't applied a function to enough arguments?)
• In the first argument of ‘print’, namely ‘it’
  In a stmt of an interactive GHCi command: print it

Instead of getting this error message, I would like see some useful information about my function f similar to the one I get with :tf (possibly even more information about f ).

How can I set up the GHCI to achieve this functionality, ie getting function's info upon entering it without :t ?

You probably can't do this today. I've opened a feature request to see about adding options to control what GHCi reports about type errors at the prompt.

GHCi will already happily show you the types of anything you type into the prompt, with the option :set +t . The only issue is that show is called on the thing, and there is no proper manner for showing functions - and the type is only printed for an expression which can be shown in a valid manner. However, you can get around this quite easily:

>newtype ShowType a = ShowType a
newtype ShowType a = ShowType a
>instance Show (ShowType a) where show _ = "The type is"
>:set +t
>ShowType const
The type is
it :: ShowType (a -> b -> a)

Unfortunately, this creates quite a lot of syntactic noise. My preferred solution is to add the following to the .ghci file:

:set +t 
instance {-# OVERLAPS #-} Show a where show _ = "The type is"

Adding such a Show instance to any real Haskell module would be a grave mistake, but within the .ghci module, it only scopes over expressions typed into the prompt, so it seems okay to me. With this, you get:

>const
The type is
it :: a -> b -> a
>show
The type is
it :: Show a => a -> String

Conveniently, when you have a function whose type is 'technically' valid but has unsatisfiable constraints, you still get a type error:

>:t \x -> x `div` (x / x)
\x -> x `div` (x / x) :: (Integral a, Fractional a) => a -> a
                         ^^^^^^^^^^^^^^^^^^^^^^^^^^

>\x -> x `div` (x / x)

<interactive>:12:1: error:
    * Ambiguous type variable `a0' arising from a use of `it'
      prevents the constraint `(Fractional a0)' from being solved.

However, the absolute simplest solution is to :set +t and to give a let statement when your expression is non- Show able:

>let _f = show
_f :: Show a => a -> String

Unfortunately, if the left-hand side is the wildcard - let _ = show - then the type is not printed.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM