简单的问题。是否可能检查仅在函数内部存在的变量的类型?
例如:
main = do
x <- something
我该如何检查 x
的类型?
在 ghci 中我不能使用 :type x
,因为x
不是全局变量。
另一种方法(与RobAgar的方法非常相似,也很hacky)是明确指定某个错误的类型作为相关局部变量,例如:
main = do
x <- getArgs
x :: () -- let's cast it to unit! ;)
print $ head x
Couldn't match expected type `()' with actual type `[String]'
这意味着“x”的实际类型是[String]。
有一个巧妙的方法:
main = do
x <- something
foo x
当你使用的函数foo
并不接受你认为x
可能具有的类型作为参数时,你会收到来自GHC的错误信息,其中包括foo
期望的类型和实际传入的类型。
你可以使用 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
这并不是一件容易的事情。如果你的something
函数在全局范围内,你可以检查该函数的类型。如果它真的在你的主函数中,它的类型应该为 IO SomeType
,其中SomeType
可能是你要找的内容。
C-c C-t
,它显示点处标识符的类型,包括局部标识符。但是,只有在您的文件通过类型检查时才会起作用。这有点显而易见的不是答案。提供一个本地绑定形式:
x <- something
x
的类型,你只需要知道something
的类型。假设something
的类型为m a
(其中m
是某个Monad),那么x
的类型必须是a
。
x
的单子类型与 do 块不同,您甚至不必将其转换为 unit。只需在 do 块的自己一行中放置x
,类型检查器就会抱怨(例如,在此情况下)它没有类型IO a
。 - Dan Burton