Преобразование IO Int в Int
Я создал комбинированный список из преобразования xmlWidget
к comboBox
с функцией castTocomboBox
и теперь я хочу получить текст или индекс активного элемента. Проблема в том, что если я использую comboBoxGetActive
функция возвращает IO Int
результат, и мне нужно знать, как я могу получить Int
значение. Я пытался читать о монадах, чтобы понять, что можно делать в такой ситуации, но, похоже, я не понимаю. Я ценю всю помощь, которую я могу получить. Я должен вероятно упомянуть, что я использую Glade
а также gtk2hs
,
3 ответа
Как правило, вы пишете что-то вроде этого:
do
x <- somethingThatReturnsIO
somethingElseThatReturnsIO $ pureFunction x
Нет никакого способа получить "Int" из "IO Int", кроме как сделать что-то еще в Ion Monad.
С точки зрения монады, приведенный выше код
somethingThatReturnsIO >>= (\x -> somethingElseThatReturnsIO $ pureFunction x)
Оператор ">>=" (произносится как "bind") делает магию преобразования "IO Int" в "Int", но отказывается передавать этот Int прямо вам. Это будет только передавать это значение в другую функцию в качестве аргумента, и эта функция должна возвращать другое значение в "IO". Медитируйте на тип привязки для монады IO в течение нескольких минут, и вы можете стать просветленным:
>>= :: IO a -> (a -> IO b) -> IO b
Первый аргумент - это ваше первоначальное значение IO Int, которое возвращает comboBoxGetActive. Вторая - это функция, которая принимает значение Int и превращает его в другое значение IO. Таким образом, вы можете обрабатывать Int, но результаты этого никогда не выходят из монады IO.
(Конечно, есть печально известное "unsafePerformIO", но на своем уровне знаний вы можете быть уверены, что если вы используете его, то делаете это неправильно.)
(На самом деле десагеринг довольно сложен, чтобы учесть неудачные сопоставления с образцом. Но вы можете притвориться, что я написал правду)
Ну, есть unsafePerformIO: http://haskell.org/ghc/docs/6.12.1/html/libraries/base-4.2.0.0/System-IO-Unsafe.html
(Если вы хотите узнать, как найти этот метод: перейдите по http://www.haskell.org/hoogle и найдите нужную подпись здесь. IO a -> a
)
Тем не менее, вы, вероятно, слышали о "Что происходит в IO остается в IO". И для этого есть очень веские причины (просто прочитайте документацию по unsafePerformIO). Таким образом, у вас, скорее всего, есть проблемы с дизайном, но для того, чтобы получить помощь от опытных Haskellers (я, конечно, нет), вам нужно описать вашу проблему более подробно.
Чтобы понять, что это за типы - шаг за шагом - сначала посмотрите, что такое Maybe и List:
data Maybe a = Nothing | Just a
data [a] = [] | a : [a]
(Может быть) другой тип, чем (а), как (может быть Int) отличается от (Int). Примерные значения типа (может быть Int):просто 5 и ничего.
Список (a) может быть записан как ([] a) и как ([a]). Примерными значениями ([Int]) являются [1,7,42] и [].
Теперь (IO a) - это тоже не то, что (a): это вычисление ввода / вывода, которое вычисляет значение типа (a). Другими словами: это скрипт или программа, которая должна быть выполнена для генерации значения типа (а). Примером (IO String) является getLine, который читает строку текста из стандартного ввода.
Теперь тип comboBoxGetActive:
comboBoxGetActive :: ComboBoxClass self => self -> IO Int
Это означает, что comboBoxGetActive - это функция (->), которая сопоставляет любой тип с экземпляром класса типов ComboBoxClass (примитивные классы типов чем-то похожи на java-интерфейсы) на (IO Int). Каждый раз, когда эта функция (->) оценивается одним и тем же входным значением этого типа (self) (каким бы ни был этот тип), это приводит к одному и тому же значению: это всегда одно и то же значение типа (IO Int), что означает, что это всегда один и тот же сценарий. Но когда вы выполняете один и тот же сценарий в разное время, он может выдавать разные значения типа (Int).
Основная функция вашей программы имеет тип (IO ()), это означает, что компилятор и система времени выполнения оценивают уравнения, которые вы программируете на этом функциональном языке, в значение main, которое будет выполнено, как только вы запустите программа.