Haskell中如何获取含局部变量的任意表达式类型?
解决Haskell中局部变量场景下的类型查询问题
我完全懂你这种困扰——在处理带局部变量(比如用<-、let、where定义的)的表达式时,:type确实派不上用场,类型孔又只会返回最泛化的类型,而本以为能精准解决的:type-at也没按预期工作,太闹心了!
给你几个实用的解决办法,亲测有效:
方案1:用
ScopedTypeVariables+临时类型注解
这是最直接的思路,先开启ScopedTypeVariables扩展,然后给你想查的局部表达式加个占位类型注解,让GHC主动报错告诉你实际类型。举个thing.hs的例子:{-# LANGUAGE ScopedTypeVariables #-} main = do x <- return (42 :: Int) let y = x + 10 -- 想查询y+5的具体类型 let _ = (y + 5) :: _ print y用
ghci thing.hs加载后,GHC会直接提示你_需要替换成Int,这个结果会完全考虑局部变量x、y的具体类型,不会泛化。方案2:借助GHC的
-ddump-types编译选项
如果你不想修改代码,可以直接用编译参数输出全量类型信息。运行命令:ghc -ddump-types thing.hs编译后会生成详细的类型输出,你只需要在输出里找到对应代码片段的类型即可。唯一的小缺点是输出内容比较多,需要自己过滤一下目标表达式的相关信息。
方案3:检查
:type-at的正确用法与GHC版本
有时候:type-at没生效是因为用法不对或者版本bug。正确的调用格式是在GHCi加载文件后,输入::type-at thing.hs 起始行 起始列 结束行 结束列注意行号和列号都是从1开始计数的,而且尽量使用GHC 8.0以上的稳定版本(旧版本可能存在局部类型查询的bug)。如果之前的参数写错了,调整后再试试应该能得到精准结果。
我个人最常用的是第一种方案,简单直接,能快速拿到符合局部上下文的类型信息,不会被泛化类型干扰。
内容的提问来源于stack exchange,提问作者JoL
相关产品推荐
相关产品推荐

