Как проверить тип локальной переменной?


Простой вопрос. Можно ли проверить тип переменной, которая существует только в функции?

Например:

main = do
       x <- something

Как я могу проверить тип x?

Я не могу сделать :type x в ghci, потому что x не является глобальным.

6 16

6 ответов:

Другой способ (очень похожий на 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].

Есть хитрый способ:

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, вероятно, то, что вы ищете.

Другим вариантом являетсяScion , который в основном является внешней оболочкой над GHC api, которая действует как сервер, предоставляющий IDE-подобные возможности для редакторов, таких как Emacs и Vim.

В readme он упоминает" экспериментальную " команду C-c C-t, которая показывает тип идентификатора в точке, включая локальные идентификаторы. Однако это будет работать только при проверке типа файла.

Это позволяет узнать тип локального объявления без компиляции файла или загрузки в него. GHCi, что означает, что он не будет нарушать ваш поток мыслей так сильно.

Это своего рода очевидный не-ответ. Дано локальное связывание вида

x <- something
Чтобы узнать тип x, вам просто нужно знать тип something. Данный something имеет вид m a (для некоторой монады m), x следовательно, он должен иметь тип a.