Haskell:获取表达式的静态类型 [英] Haskell: getting the static type of an expression

查看:105
本文介绍了Haskell:获取表达式的静态类型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述



理想情况下,它的签名类似于

  getStaticType :: a  - >字符串

a = getStaticType(1 + 2)
- a =(Num t)=> t

b = getStaticType zipWith
- - b =(a - > b - > c) - > [a] - > [b] - > [c]

您可以这样做:

  import Data.Typeable 

getStaticType ::可键入的a => a - >字符串
getStaticType = show。 typeOf

请注意,该类型必须是 Typeable 。您可以使用 DeriveDataTypeable Haskell语言扩展和 ...自动派生 Typeable ... deriving(Typeable ,...)



另请注意,多态类型不能用这种方式标识;您必须始终使用特定的类型调用函数,因此您永远无法获得您在GHCi中使用编译好的Haskell代码获得的多态类型信息。



< GHCi的做法是使用GHC API来分析包含类型信息的中介Haskell抽象语法树(AST)。 GHCi没有与典型的Haskell编译程序相同的受限环境;它可以做很多事情来了解更多关于其环境的信息。



使用TemplateHaskell,你可以这样做;首先,创建这个模块:

 模块TypeOf其中

导入Control.Monad

import Language.Haskell.TH
import Language.Haskell.TH.Syntax

getStaticType :: Name - > Q Exp
getStaticType = lift< =< fmap pprint。然后,在不同模块中(非常重要),您可以请执行以下操作:

  { - #LANGUAGE TemplateHaskell# - } 

import TypeOf

main = putStrLn $(getStaticType'zipWith)

该程序输出:

  GHC.List.zipWith :: forall a_0 b_1 c_2。 (a_0→b_1→c_2)→> 
[a_0] - > [b_1] - > [c_2]

您可以使用比 pprint 函数;请查看 Language.Haskell.TH.Ppr 模块。


I'm looking for a function that does what the GHCi :type command does.

Ideally, it would have a signature something like

getStaticType :: a -> String

a = getStaticType (1+2)
-- a = "(Num t) => t"

b = getStaticType zipWith
-- b = "(a -> b -> c) -> [a] -> [b] -> [c]"

(Note: this has nothing to do with Data.Dynamic. I just want the static type inferred from the compiler. In fact the function wouldn't need a runtime implementation at all, as all calls to it could be inlined as constants at compile time. I'm assuming it exists somewhere, since GHCi can do it)

解决方案

You can do it like this:

import Data.Typeable

getStaticType :: Typeable a => a -> String
getStaticType = show . typeOf

Note that the type must be an instance of Typeable. You can derive Typeable automatically using the DeriveDataTypeable Haskell language extension and ... deriving (Typeable, ...).

Also note that polymorphic types cannot be identified in this way; you must always call a function with a specific type, so you can never get that polymorphic type information that you get in GHCi with compiled Haskell code.

The way GHCi does it is that it uses the GHC API to analyse an intermediary Haskell abstract syntax tree (AST) that contains type information. GHCi does not have the same restricted environment that your typical compiled Haskell program does; it can do lots of stuff to find out more information about its environment.

With TemplateHaskell, you can do it like this; first, create this module:

module TypeOf where

import Control.Monad

import Language.Haskell.TH
import Language.Haskell.TH.Syntax

getStaticType :: Name -> Q Exp
getStaticType = lift <=< fmap pprint . reify

Then, in a different module (very important), you can do the following:

{-# LANGUAGE TemplateHaskell #-}

import TypeOf

main = putStrLn $(getStaticType 'zipWith)

This program outputs:

GHC.List.zipWith :: forall a_0 b_1 c_2 . (a_0 -> b_1 -> c_2) ->
                                         [a_0] -> [b_1] -> [c_2]

You can use a better pretty-printer than the pprint function; take a look at the Language.Haskell.TH.Ppr module.

这篇关于Haskell:获取表达式的静态类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆