2017-09-13 46 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

相关问题