2017-09-13 48 views
6

當我進入GHCI命令:t我看到的多態類型:如何在應用類型默認規則的情況下打印ghci中的多態函數(或值)類型?

ghci> :t 42 
42 :: Num t => t 
ghci> :t div 
div :: Integral a => a -> a -> a 

但經過我實際評估這些功能我看到的類型默認規則的結果。根據Haskell報告和/或ghc實現應用類型違約規則後,有沒有一些命令或能力可以在ghci中觀察如何更改類型?

+0

你如何看到類型違約規則的結果? ':t 42 \'div \'2'顯示'Integral a => a'',並且let-bindings的結果等等也是 –

+0

@ n.m。我是在談論實際結果。像'2^100'' div'' 2'打印'633825300114114700748351602688',因爲這種情況下的默認類型是'Integer'。即使'ghci'說這個常量的類型是多態的,實際上它是特定的,我想看看使用了哪種單形類型。 – Shersh

+1

@Shersh雖然這只是GHCi。 REPL選擇一個類型(在本例中爲'Integer'),因爲它必須顯示一些內容。在「真實」代碼中,它將是多態的,直到上下文選擇一種類型。 –

回答

5

您可以通過打開單態的限制,然後將其綁定到一個新的名稱做到這一點:

Prelude> :set -XMonomorphismRestriction 
Prelude> let n = 42 
Prelude> :t n 
n :: Integer 
Prelude> let p = (^) 
Prelude> :t p 
p :: Integer -> Integer -> Integer 
Prelude> let e = (**) 
Prelude> :t e 
e :: Double -> Double -> Double 
Prelude> let d = div 
Prelude> :t d 
d :: Integer -> Integer -> Integer 

如果你不喜歡,必須始終定義一個新的變量,就可以解決這個問題通過使用

Prelude> :def monotype (\e -> return $ ":set -XMonomorphismRestriction\nlet defaulted = "++e++"\n:t defaulted") 

(你可以把它放到在你.ghci文件總是有可用的命令),然後

Prelude> :monotype (^) 
defaulted :: Integer -> Integer -> Integer 

當然,啓用單態限制的隱藏全局副作用是非常難看的,但是噢...

+0

它適用於我的'div'(8.0.2)。也許要求':t d' :) –

+0

是的,在8.3和7.10中也可以,實際上寫':t d'而不是':t div'。我的手指輸入得太快了...... – leftaroundabout

+0

這真的很有幫助!不完美(因爲我不能寫':t div'),但已經夠好了。 – Shersh

4

不是一個完美的解決方案,但它可能是第一步。

> import Data.Typeable 
> let withType x = (x, typeOf x) 
> withType [] 
([],[()]) 
> withType 56 
(56,Integer) 

需要注意的是,因爲類型a被改爲(a,TypeRep),GHCI將無法使用其全部違約魔力。不過,其中一些可以顯示。

GHCi的:set +t選項也很有趣,但在GHCi默認之前打印多態類型似乎。

+0

這是一個有趣的解決方案! – Shersh

相關問題