Используя Haskell "Maybe", объявления типов [вопрос новичка] - PullRequest
6 голосов
/ 16 июля 2011

Я начал экспериментировать с Haskell и у меня возникла проблема.qqq - это функция, которая должна печатать одну строку, если она вызывается с помощью «Nothing», и печатать другие вещи, если она вызывается с помощью «Justthing».

Первая попытка выглядит так:

qqq Nothing = print "There isn't anything to be printed."
qqq (Just x) = print "There is something to be printed." >> print x

main :: IO ()
main = qqq (Just 43)

Но:

  • , когда я пытаюсь сделать main = qqq (Nothing), он терпит неудачу ("переменная неоднозначного типа" a0 "в ограничении: (показать a0), возникающая из использования 'qqq'")
  • Когда я хочу добавить сигнатуру типа в случае неудачи:
    • qqq :: Maybe x => x -> IO () -> Type constructor 'Maybe' used as a class -> Но не так ли?
    • qqq :: (Maybe x) -> IO ().Теперь сама подпись выглядит удачной.Но main = qqq (Just 43) начинает работать с этой загадочной (Show a0) ошибкой, как в main = qqq (Nothing) случае.

Вопросы:

  1. Зачем вызывать qqq сNothing так отличается от звонка с Just 43?
  2. Что такое (Show a0)?Упоминается только в сообщениях об ошибках.Любые попытки использовать его приводят к чему-то вроде «Показать не в области видимости».
  3. Что такое правильная сигнатура типа для этого?Как сделать так, чтобы на Хаскеле была напечатана подпись типа печати?Ожидая что-то вроде:
f 0 = 2
f x = (f (x-1)) + 3

main = print get_type_as_string(f)
-- prints "Number -> Number"

1 Ответ

9 голосов
/ 16 июля 2011

Тип qqq:

qqq :: Show a => Maybe a -> IO ()

Это означает, что qqq принимает один параметр типа Maybe a и возвращает действие ввода-вывода без значения с ограничением , что a реализует класс типов Show.Чтобы узнать, что такое Show, вы можете использовать :i Show в ghci.

Show - это класс типов, который требует, чтобы значение типа могло быть преобразовано в строку.qqq имеет ограничение, потому что print хочет распечатать значение (print имеет тип Show a => a -> IO ()).Maybe это не класс типов, а тип данных.Вы можете узнать больше о типах классов здесь .

Вы можете позволить GHC определять сигнатуру типа, либо набрав функцию в файле .hs, затем загрузив файл с помощью ghci (ghci Myfile.hs)и затем введите :t qqq для отображения типа.Вы также можете определить функцию в интерактивном сеансе с помощью let qqq n = case n of { Nothing -> print "abc"; Just x -> print "def" >> print x } (выглядит немного иначе, потому что определение функции должно быть в одной строке в ghci, но смысл тот же).

Когда основные вызовыqqq с qqq (Just 43), ясно, что конкретный тип Maybe a является числовым типом (по умолчанию ghci - Integer), поэтому qqq имеет конкретный тип Maybe Integer -> IO ().Однако основные вызовы qqq с qqq Nothing, a могут быть любыми (это неоднозначно), и ghci сообщает об ошибке.

...