Контрольная монада (когда и т.п.) и типы возврата, отличные от IO()

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

Проблема в том, что когда ожидается, что тип возвращаемого значения будет IO(), но я хочу, чтобы он (или моя собственная версия) работал для IO (Response ByteString)

Это мой код функции:

mayNotifyDs :: Bool -> String -> ByteString -> IO (Response ByteString)
mayNotifyDs hasRel specName details =
  when hasRel (post addr ("dummy" := details))
    where addr = "http://127.0.0.1:8082/dummydir/" ++ specName

edit: «Печать» пробралась в код, который я изначально опубликовал, это было то, с чем я экспериментировал, и с тех пор я его удалил. Я могу использовать печать, но тогда мне также нужно использовать unsafeLocalState из Foreign.marshall, а это не рекомендуется, не так ли? Код в этом случае будет таким же, но с when hasRel (print $ unsafeLocalState (post addr ("dummy" := details)))


person John Brown    schedule 19.01.2018    source источник
comment
Ну и что вы хотите, чтобы результат был, если условие не выполнено? Как бы выглядел ваш код, если бы он был написан с помощью if…then…else?   -  person leftaroundabout    schedule 19.01.2018
comment
print возвращает (), так что должно подойти. Откуда должна появиться байтовая строка ответа?   -  person nnnmmm    schedule 19.01.2018
comment
Похоже, вам нужен возвращаемый тип Maybe (IO (Response ByteString)) с чем-то вроде if hasRel then Just (post addr ...) else Nothing.   -  person hnefatl    schedule 19.01.2018


Ответы (1)


Я остановился на решении здесь. В конце концов я использовал unsafeLocalState, увидев, что я уже проверяю, существует ли указанное значение, первоначально с помощью bool, но в конечном итоге с помощью монады may.

редактировать: обратите внимание, что я не хочу здесь ошибаться; оба случая должны печатать что-то для целей ведения журнала.

edit2: изменить мой ответ, чтобы он соответствовал тому, что упомянул здесь Ли Ян, считая его лучшим решением.

mayNotifyDs :: String -> Maybe ByteString -> IO ()
mayNotifyDs specName details = case details of
  (Just _) -> post addr ("dummy" := details) >>= print
  Nothing  -> putStrLn "Message about fail"
  where addr = "http://127.0.0.1:8082/dummydir/" ++ specName
person John Brown    schedule 19.01.2018
comment
Зачем тебе unsafeLocalState здесь? Разве ты не хочешь просто (Just _) -> post addr ("dummy" := details) >>= print? - person Lee; 19.01.2018
comment
Да, unsafeLocalState (или unsafePerformIO) здесь не нужны и нецелесообразны. Просто используйте привязку: do { result <- post addr ("dummy" := details); print result } или >>=/=<<, как упоминает Ли. - person Jon Purdy; 20.01.2018
comment
да не могу поверить, что я этого не видел. Спасибо. - person John Brown; 22.01.2018