You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Haskell程序内实现类似ghci :info的函数信息打印功能

运行时打印Haskell自动推导函数类型的实现方案

首先明确核心限制:Haskell是静态编译语言,类型推导全流程在编译阶段完成,大部分编译期元数据不会保留到运行时,因此无法在最终编译出的可执行程序里100%复刻ghci中:info命令的全部输出——:info附带的函数定义位置、运算符固定度、关联类型类实例等信息属于GHC交互前端专属的元数据,不会被打包到可执行文件中。但你可以借助GHC内置的运行时类型反射能力,实现和:type命令完全一致的类型打印效果,满足查看自动推导类型的核心需求。

可直接运行的实现代码

你需要开启三个常用GHC扩展,借助Typeable类型类实现通用打印函数。所有标准Haskell类型、你自定义的函数默认都实现了Typeable类,不需要手动编写任何实例逻辑:

{-# LANGUAGE AllowAmbiguousTypes #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeApplications #-}

import Type.Reflection (Typeable, typeRep)

print_info :: forall a. Typeable a => a -> IO ()
print_info _ = putStrLn $ "自动推导类型: " ++ show (typeRep @a)

-- 测试函数,不预先添加类型标注
f x = 2*x

main :: IO ()
main = do
  print_info f

编译运行上述代码,将输出:

自动推导类型: Integer -> Integer

输出结果和ghci中执行:type f得到的类型完全一致。

注意事项

  • 单态限制的影响:GHC默认开启单态限制,没有标注类型的多态函数会被自动推导为具体类型,比如无约束的多态恒等函数g x = x直接传入print_info时,会被推导为单态结果。如果需要打印多态类型,可以在文件头添加{-# LANGUAGE NoMonomorphismRestriction #-}扩展关闭单态限制,或者显式传入带多态类型标注的值,例如print_info (id :: forall a. a -> a)即可正确输出forall a. a -> a。
  • 更便捷的ghci使用方式:如果你觉得手动加载文件、敲:info命令繁琐,可以在用户目录下的.ghci配置文件中添加自定义短命令别名:
    :def i \func -> return $ ":info " ++ func
    
    配置完成后,启动ghci加载代码文件,只需要输入:i f就能直接查看完整的函数信息,不需要敲完整命令。

内容的提问来源于stack exchange,提问作者Anonymous

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.27 17:18:24