Haskell "ничего не делать" IO, или если без другого - PullRequest
74 голосов
/ 07 мая 2009

Я хочу сделать в Хаскеле что-то похожее на:

main1 = do s <- getLine
           if s == "foo" then putStr "You entered foo"

Очевидно, что это не законно, поскольку нет else. Я подумал об одной альтернативе:

nop :: IO ()
nop = sequence_ []

main2 = do s <- getLine
           if s == "foo" then putStr "You entered foo" else nop

Это немного многословно, но я бы согласился на это в случае необходимости. Я был бы удивлен, если бы не было встроенной версии nop, хотя.

В качестве альтернативы:

doIf :: Bool -> IO () -> IO ()
doIf b m = if b then m else nop

main3 = do s <- getLine
           doIf (s == "foo") (putStr "You entered foo")

Это более кратко, но синтаксис не особенно хорош. Опять же, я бы не удивился, обнаружив что-то встроенное, что уже существует.

Какой предпочтительный способ сделать это?

Ответы [ 2 ]

103 голосов
/ 07 мая 2009

Самый простой способ сделать неоперацию в монаде:

return ()

Однако, для конкретной идиомы, которую вы делаете, для вас уже создан комбинатор:

import Control.Monad
main = do s <- getLine
          when (s == "foo") $ putStr "You entered foo"

Этот , когда комбинатор ведет себя так же, как ваш комбинатор doIf:)

19 голосов
/ 07 мая 2009

Вы можете использовать Hoogle для поиска функций, в данном случае: when.

В Google вы можете ввести сигнатуру типа, и он попытается найти подходящие функции в стандартных библиотеках, унифицировав типы и изменив порядок аргументов.

В вашем случае вы можете просто ввести тип вашей функции doIf: Bool -> IO () -> IO () . when является третьим ответом здесь, его обратный unless также там.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...