2016-12-28 66 views
3

要看到在Haskell GHCI函數的簽名,我有:t前綴是:如何設置Haskell的GHCI以互動方式將函數評估爲其簽名(類型)而不是獲取錯誤?

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 

而不是收到此錯誤信息,我想看到一個類似於我:t f(甚至可能更多的信息,讓我的功能f一些有用的信息有關f )。

如何設置GHCI以實現此功能,即獲取功能的信息,無需輸入:t

+0

非答案:':i'命令顯示有關超出其類型的值的一些額外信息;它也適用於類(但是,它是一個像':t'一樣的前綴命令)。此外,':set + t'將使GHCi打印在命令提示符下成功評估的任何類型的任何東西(但是,它不利於您談論的無實例顯示的情況)。 – duplode

+0

我認爲你應該以不壓低GHCi的方式來重述這個問題。你想要的東西似乎相當合理;如果你問得好,人們可能會對幫助更感興趣。 – dfeuer

+0

那麼錯誤信息應該告訴你repl是如何工作的。我不認爲你想要什麼是可能的。不過這可能是個好主意。或者這可能是一個任意的特殊情況,會讓人們感到困惑。 – jberryman

回答

4

你今天可能不能這樣做。我已打開a feature request以查看有關添加選項以控制GHCi在提示時報告類型錯誤的信息。

+0

你的意思是我甚至不能在這種情況下重新配置在'f'上運行的函數('Show'?)? –

+0

@DmitriZaitsev,你可以配置什麼函數用於在GHCi中打印值,但這不會對你有所幫助,除非我對你後面的內容感到困惑。 – dfeuer

+0

我在輸入'f'後打印':t f'(錯誤消息之前)。 –

2

GHCi已經開心地向您顯示您在提示中鍵入的任何類型,選項爲:set +t。唯一的問題是show被調用的東西,並沒有適當的方式來顯示函數 - 類型只打印一個表達式可以以有效的方式顯示。但是,您可以解決這個問題很容易:

>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 - 那麼類型不會被打印。