Как вы проверяете тип локальной переменной? - PullRequest
17 голосов
/ 09 февраля 2012

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

Например:

main = do
       x <- something

Как проверить тип x?

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

Ответы [ 6 ]

13 голосов
/ 09 февраля 2012

Другой способ (очень похожий на RobAgar и хакерский) также состоит в том, чтобы явно указать некоторый неправильный тип для рассматриваемой локальной переменной, например ::

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].

12 голосов
/ 09 февраля 2012

Есть хакерский путь:

main = do
       x <- something
       foo x

где foo - любая старая функция, которая не принимает аргумент типа, который, как вы думаете, x может быть. Вы получите приятную ошибку от GHC, которая включает тип, ожидаемый foo , и тип, фактически переданный в .

5 голосов
/ 17 февраля 2012

Вы можете использовать отладчик 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 голосов
/ 09 февраля 2012

Нет простого способа сделать это.Если ваша something функция находится в глобальной области видимости, вы можете проверить тип этой функции.Если он действительно входит в вашу основную функцию, его тип будет IO SomeType, где SomeType, вероятно, то, что вы ищете.

3 голосов
/ 09 февраля 2012

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

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

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

2 голосов
/ 10 февраля 2012

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

x <- something

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

...