gpt4 book ai didi

Haskell:获取表达式的静态类型

转载 作者:行者123 更新时间:2023-12-04 01:42:54 25 4
gpt4 key购买 nike

我正在寻找一个执行 GHCi :type 命令的功能。

理想情况下,它会有一个类似的签名

getStaticType :: a -> String

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

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

(注意:这与 Data.Dynamic 无关。我只想要从编译器推断出的静态类型。事实上,该函数根本不需要运行时实现,因为对它的所有调用都可以在编译时内联为常量时间。我假设它存在于某个地方,因为 GHCi 可以做到)

最佳答案

你可以这样做:

import Data.Typeable

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

请注意,类型必须是 Typeable 的实例。 .可以推导出 Typeable自动使用 DeriveDataTypeable Haskell 语言扩展和 ... deriving (Typeable, ...) .

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

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

使用 TemplateHaskell,您可以这样做;首先,创建这个模块:
module TypeOf where

import Control.Monad

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

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

然后,在 不同的模块 (非常重要),您可以执行以下操作:
{-# 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 更好的 pretty-print 功能;看看 Language.Haskell.TH.Ppr 模块。

关于Haskell:获取表达式的静态类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10399685/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com