當我進入GHCI命令:t
我看到的多態類型:如何在應用類型默認規則的情況下打印ghci中的多態函數(或值)類型?
ghci> :t 42
42 :: Num t => t
ghci> :t div
div :: Integral a => a -> a -> a
但經過我實際評估這些功能我看到的類型默認規則的結果。根據Haskell報告和/或ghc實現應用類型違約規則後,有沒有一些命令或能力可以在ghci中觀察如何更改類型?
當我進入GHCI命令:t
我看到的多態類型:如何在應用類型默認規則的情況下打印ghci中的多態函數(或值)類型?
ghci> :t 42
42 :: Num t => t
ghci> :t div
div :: Integral a => a -> a -> a
但經過我實際評估這些功能我看到的類型默認規則的結果。根據Haskell報告和/或ghc實現應用類型違約規則後,有沒有一些命令或能力可以在ghci中觀察如何更改類型?
您可以通過打開單態的限制,然後將其綁定到一個新的名稱做到這一點:
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
當然,啓用單態限制的隱藏全局副作用是非常難看的,但是噢...
它適用於我的'div'(8.0.2)。也許要求':t d' :) –
是的,在8.3和7.10中也可以,實際上寫':t d'而不是':t div'。我的手指輸入得太快了...... – leftaroundabout
這真的很有幫助!不完美(因爲我不能寫':t div'),但已經夠好了。 – Shersh
不是一個完美的解決方案,但它可能是第一步。
> import Data.Typeable
> let withType x = (x, typeOf x)
> withType []
([],[()])
> withType 56
(56,Integer)
需要注意的是,因爲類型a
被改爲(a,TypeRep)
,GHCI將無法使用其全部違約魔力。不過,其中一些可以顯示。
GHCi的:set +t
選項也很有趣,但在GHCi默認之前打印多態類型似乎。
這是一個有趣的解決方案! – Shersh
你如何看到類型違約規則的結果? ':t 42 \'div \'2'顯示'Integral a => a'',並且let-bindings的結果等等也是 –
@ n.m。我是在談論實際結果。像'2^100'' div'' 2'打印'633825300114114700748351602688',因爲這種情況下的默認類型是'Integer'。即使'ghci'說這個常量的類型是多態的,實際上它是特定的,我想看看使用了哪種單形類型。 – Shersh
@Shersh雖然這只是GHCi。 REPL選擇一個類型(在本例中爲'Integer'),因爲它必須顯示一些內容。在「真實」代碼中,它將是多態的,直到上下文選擇一種類型。 –