2017-09-13 4 views
6

Quand je rentre commande :t dans GHCi Je vois le type polymorphes:Comment imprimer le type de fonction (ou valeur) polymorphe dans ghci avec des règles de type par défaut appliquées?

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

Mais après avoir fait ces fonctions évalue je vois en raison des règles en défaut de type. Y a-t-il une commande ou une capacité à observer dans ghci comment le type sera changé après que les règles de défaut de type aient été appliquées selon le rapport de Haskell et/ou l'implémentation de ghc?

+0

Comment voyez-vous le résultat des règles par défaut de type? ': t 42 \' div \ '2' montre' Integral a => a', ainsi que les résultats de let-bindings, etc. –

+0

@ n.m. Je parlais du résultat réel. Comme '2^100 \' div \ '2' affiche' 633825300114114700748351602688' parce que le type par défaut est 'Integer'. Même si 'ghci' dit que le type de cette constante est polymorphe, en réalité c'est spécifique et je veux voir quel type monomorphe est utilisé. – Shersh

+1

@Shersh C'est juste GHCi. Le REPL choisit un type ('Integer', dans ce cas) car il doit afficher quelque chose. Dans le code "réel", il sera polymorphe jusqu'à ce que le contexte prenne un type. –

Répondre

5

Vous pouvez le faire en tournant sur la restriction de monomorphisme et lie alors à un nouveau nom:

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 

Si vous ne croyez pas la nécessité de toujours définir une nouvelle variable, vous pouvez contourner ce en utilisant

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

(vous pouvez le mettre dans votre fichier .ghci d'avoir toujours la commande disponible) puis

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

Bien sûr, l'effet secondaire global caché de permettre la restriction de monomorphisme est extrêmement moche, mais oh bien ...

+0

Cela fonctionne pour 'div' pour moi (8.0.2). Peut-être demander ': t d' :) –

+0

Ouais, fonctionne également en 8.3 et 7.10, en écrivant réellement': t d' au lieu de ': t div'. Mes doigts tapés trop vite là-bas ... – leftaroundabout

+0

C'est vraiment utile! Pas parfait (parce que je ne peux pas écrire ': t div') mais déjà assez bon. – Shersh

4

Pas une solution parfaite, mais ce pourrait être une première étape.

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

Notez que, puisque le type a se transforme en (a,TypeRep), GHCi n'utilisera toute sa magie en défaut. Pourtant, certains d'entre eux peuvent être montrés.

L'option :set +t de GHCi est également intéressante, mais imprime le type polymorphe avant le défaut de GHCi, semble-t-il.

+0

C'est une solution intéressante! – Shersh