Как вы проверяете тип локальной переменной? - программирование
Подтвердить что ты не робот

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

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

Например:

main = do
       x <- something

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

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

4b9b3361

Ответ 1

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

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

Тогда ghci даст нам ошибку:

Couldn't match expected type `()' with actual type `[String]'

который показывает, что фактическим типом "x" является [String].

Ответ 2

Существует хакерский способ:

main = do
       x <- something
       foo x

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

Ответ 3

Вы можете использовать отладчик 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 - это, вероятно, то, что вы ищете.

Ответ 5

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

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

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

Ответ 6

Это своего рода очевидный отказ от ответа. Учитывая локальную привязку формы

x <- something

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