如何检查本地变量的类型?

19

简单的问题。是否可能检查仅在函数内部存在的变量的类型?

例如:

main = do
       x <- something

我该如何检查 x 的类型?

在 ghci 中我不能使用 :type x,因为x不是全局变量。

6个回答

15

另一种方法(与RobAgar的方法非常相似,也很hacky)是明确指定某个错误的类型作为相关局部变量,例如:

main = do
  x <- getArgs
  x :: () -- let's cast it to unit! ;)
  print $ head x

然后 ghci 会给我们报错:
Couldn't match expected type `()' with actual type `[String]'

这意味着“x”的实际类型是[String]。


2
实际上,假设 x 的单子类型与 do 块不同,您甚至不必将其转换为 unit。只需在 do 块的自己一行中放置 x,类型检查器就会抱怨(例如,在此情况下)它没有类型 IO a - Dan Burton

12

有一个巧妙的方法:

main = do
       x <- something
       foo x

当你使用的函数foo并不接受你认为x可能具有的类型作为参数时,你会收到来自GHC的错误信息,其中包括foo期望的类型和实际传入的类型。


6

你可以使用 GHCi 调试器:

> ghci a.hs
GHCi, version 7.0.4: http://www.haskell.org/ghc/  :? for help
Loading package ghc-prim ... linking ... done.
Loading package integer-gmp ... linking ... done.
Loading package base ... linking ... done.
Loading package ffi-1.0 ... linking ... done.
[1 of 1] Compiling Main             ( a.hs, interpreted )
Ok, modules loaded: Main.
*Main> :break 4
Breakpoint 0 activated at a.hs:4:8-14
*Main> :main
Stopped at a.hs:4:8-14
_result :: IO String = _
[a.hs:4:8-14] *Main> :list
3  main = do
4    x <- getLine
          ^^^^^^^
5    return x
[a.hs:4:8-14] *Main> :step
asd
Stopped at a.hs:5:3-10
_result :: IO String = _
x :: String = _
[a.hs:5:3-10] *Main> :t x
x :: String

4

这并不是一件容易的事情。如果你的something函数在全局范围内,你可以检查该函数的类型。如果它真的在你的主函数中,它的类型应该为 IO SomeType,其中SomeType可能是你要找的内容。


3
另一个选择是Scion,它基本上是GHC API的外部包装器,作为服务器为像Emacs和Vim这样的编辑器提供类似IDE的功能。
在自述文件中,它提到了“实验性”命令C-c C-t,它显示点处标识符的类型,包括局部标识符。但是,只有在您的文件通过类型检查时才会起作用。
这使您可以找出局部声明的类型,而无需编译文件或加载到GHCi中,这意味着它不会过多干扰您的思路流程。

2

这有点显而易见的不是答案。提供一个本地绑定形式:

x <- something

为了知道x的类型,你只需要知道something的类型。假设something的类型为m a(其中m是某个Monad),那么x的类型必须是a

是的,这是不可否认的事实,但有时会变得有点复杂。直接检查是很好的。 - Nick Brunt

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接