2016-12-28 23 views
3

Чтобы увидеть подпись функция в Haskell в GHCI, я должен добавить к ней префикс :t:Как настроить GHCI от Haskell для интерактивной оценки функций для их подписи (типа) вместо получения ошибок?

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

Но типирование, что префикс каждый раз, когда быстро растет старый. Если я оставлю его, я получаю сообщение об ошибке:

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 

Вместо того, чтобы получить это сообщение об ошибке, я хотел бы видеть некоторую полезную информацию о моей функции f, подобной той, я получаю с :t f (возможно, даже больше информации о f).

Как настроить GHCI для достижения этой функциональности, т. Е. Получить информацию о функциях после ввода без :t?

+0

Не ответы: команда ': i' показывает дополнительную информацию о значении, выходящем за его тип; он также работает с классами (однако это команда префикса, как ': t'). Кроме того, ': set + t' приведет к тому, что GHCi напечатает тип всего, что было успешно оценено в командной строке (однако, к сожалению, это не помогает в ситуации без экземпляра для показа, о которой вы говорите). – duplode

+0

Я думаю, вы должны перефразировать вопрос таким образом, чтобы не подавать GHCi. То, что вы хотите, кажется довольно разумным; люди, скорее всего, будут больше заинтересованы в том, чтобы помочь, если вы спросите красиво. – dfeuer

+0

Ну, сообщение об ошибке должно подсказывать вам, как работает реплика. Я не думаю, что вы хотите. Это может быть хорошей идеей.Или это может быть произвольный случай, который бы смутил людей. – jberryman

ответ

4

Возможно, вы сегодня не можете этого сделать. Я открыл a feature request, чтобы узнать о добавлении параметров для управления тем, что GHCi сообщает о ошибках типа в подсказке.

+0

Вы имеете в виду, что я не могу даже перенастроить функцию ('Show'?), Которая работает на' f' в этом случае? –

+0

@DmitriZaitsev, вы можете настроить, какая функция используется для печати значений в GHCi, но это вам не поможет, если я не смущен тем, что вам нужно. – dfeuer

+0

Я печатаю ': t f' (перед сообщением об ошибке) при вводе' f'. –

2

GHCi уже с радостью покажет вам типы всего, что вы введете в приглашение, с опцией :set +t. Единственная проблема заключается в том, что на эту вещь вызывается , и нет надлежащего способа отображения функций - и тип печатается только для выражения, которое может быть показано действительным образом. Тем не менее, вы можете обойти это довольно легко:

>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) 

К сожалению, это создает довольно синтаксический шум. Я предпочитаю решение добавить следующее в .ghci файла:

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

Добавление такой Show экземпляр для любого реального модуля Haskell был бы серьезной ошибкой, но в пределах .ghci модуля, он прицелы только над выражениями, напечатанных в подскажите, так что мне кажется хорошо. При этом, вы получите:

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

Удобно, когда у вас есть функция, тип которого является «технически» действует, но имеет невыполнимые ограничения, вы все равно получите ошибку типа:

>: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. 

Однако , абсолютным простейшим решением является :set +t и дать инструкцию let, если ваше выражение не Show способно:

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

К сожалению, если левая сторона является подстановочным знаком - let _ = show - тогда тип не печатается.