Предложение Haskell do с несколькими типами монад
Я использую графическую библиотеку в Haskell под названиемТрехгрошовая-GUI, В этой библиотеке основная функция возвращаетUI
монадный объект. Это вызывает у меня сильную головную боль, как при попытке распаковатьIO
значения в локальные переменные я получаю сообщения об ошибках различных типов монад.
Вот пример моей проблемы. Это слегка измененная версия стандартной основной функции, как показано в примере кода Threepenny-GUI:
main :: IO ()
main = startGUI defaultConfig setup
setup :: Window -> UI ()
setup w = do
labelsAndValues <- shuffle [1..10]
shuffle :: [Int] -> IO [Int]
shuffle [] = return []
shuffle xs = do randomPosition <- getStdRandom (randomR (0, length xs - 1))
let (left, (a:right)) = splitAt randomPosition xs
fmap (a:) (shuffle (left ++ right))
Обратите внимание на пятую строку:
labelsAndValues <- shuffle [1..10]
Который возвращает следующую ошибку:
Couldn't match type ‘IO’ with ‘UI’
Expected type: UI [Int]
Actual type: IO [Int]
In a stmt of a 'do' block: labelsAndValues <- shuffle [1 .. 10]
Что касается моего вопроса, как мне распаковатьIO
функция с использованием стандартной стрелки обозначения (<-
), и продолжайте иметь эти переменные какIO ()
скорее, чемUI ()
так что я могу легко передать их другим функциям.
В настоящее время единственным решением, которое я нашел, было использованиеliftIO
, но это вызывает преобразование вUI
тип монады, в то время как я на самом деле хочу продолжать использоватьIO
тип.