:t
inghci
が式の型を与えることは誰もが知っています。
Prelude> :t [1..]
[1..] :: (Enum t, Num t) => [t]
私が必要としているのは:t
、haskell スクリプト (私はそれを呼び出しますtypeStr
) に相当するものです:
main = putStrLn $ typeStr [1..]
(Enum t, Num t) => [t]
画面上のようなものを印刷できます。
それは可能ですか?
はい、いくつかの方法があります。
1.動的型付けを使用する
単相型の単純なケースでは、 Typeable インスタンスを使用できます。
Data.Dynamic> typeOf [1..]
[Integer]
2.ランタイム評価を使用する
ただし、これを適切に行うには (ポリモーフィックな値の型を取得するには)、完全な GHC 型チェッカーが必要です。たとえば、ghc-api ライブラリとその素敵なラッパー、ヒントを介して:
Language.Haskell.Interpreter> runInterpreter $ typeOf "[1..]"
Right "(P.Enum t, P.Num t) => [t]"
動的に呼び出された完全な GHC 型チェッカーを使用して正しく推論された型です。
はい、できます。タイプが次のインスタンスである限り、次のようになりますData.Typeable
。
import Data.Typeable
typeStr :: Typeable a => a -> String
typeStr a = show $ typeOf a
ただし、引数は特定の型になるため、可能な限り最も一般的な型を取得することはないと思います。たとえば、ghciでのtypeStr [1..]
利回り。[Integer]
簡単な答え:いいえ。
Haskellは通常、実行時まで型が不明な式を記述できないため、そもそも実行時型のルックアップは必要ありません。
そうは言っても、動的型付けを行う方法はいくつかあり、おそらくそれは型署名の印刷をサポートする可能性があります...しかし、これはおそらくあなたがやりたいことではありません。
もう1つの可能性は、テンプレートHaskellを使用して、コンパイル時に型シグネチャを検索することです。誰かがすでにそのためのコードを書いているかどうかはわかりません...