Haskell “有条件”的较短方式;返回()”;在哈斯凯尔的单子链中(>;>;,>;=)?
我有一个简单的代码,它读取一个字符串并无限期地打印它Haskell “有条件”的较短方式;返回()”;在哈斯凯尔的单子链中(>;>;,>;=)?,haskell,Haskell,我有一个简单的代码,它读取一个字符串并无限期地打印它 main :: IO () main = getLine >>= putStrLn >> main 现在,如果行是“退出”或“退出”,我想在调用getLine后退出 我的尝试: main :: IO () main = do line <- getLine if line == "exit" || line == "quit" then return () else putStrLn line
main :: IO ()
main = getLine >>= putStrLn >> main
现在,如果行是“退出”或“退出”,我想在调用getLine
后退出
我的尝试:
main :: IO ()
main = do
line <- getLine
if line == "exit" || line == "quit"
then return ()
else putStrLn line >> main
main::IO()
main=do
行>主
在我看来并不习惯。有更好的方法吗?
控制.Monad。除非
(这是比较流行的一种方法,当
时)将此模式从代码中提取出来:
import Control.Monad (unless)
main = do
line <- getLine
unless (line == "exit" || line == "quit") $ do
putStrLn line
main
-- or
when (line /= "exit" && line /= "quit") $ do
putStrLn line
main
import Control.Monad(除非)
main=do
line由于使用if/else和do符号,您似乎关心代码的顺序感觉。您可以尝试以下方法:
main = getLine >>= proc
where
proc s | s == "exit" || s == "quit" = return ()
| otherwise = putStrLn s >> main
追求时尚:
module Main where
import Control.Monad
import Control.Monad.Trans.Maybe
import Control.Monad.Trans.Class
import System.IO
isValid s = s ≠ "quit" && s ≠ "exit"
getL ∷ MaybeT IO String
getL = do s ← lift getLine
guard (isValid s)
return s
main = runMaybeT main' where
main' = do
lift $ putStr "Enter line: "
lift $ hFlush stdout
s ← getL
lift $ putStrLn $ "Your line is: " ⧺ s
main'
使用管道-4.0
:
import Pipes
import qualified Pipes.Prelude as P
main = runEffect $
P.stdinLn >-> P.takeWhile (`notElem` ["quit", "exit"]) >-> P.stdoutLn
我们可以创建一个助手函数,该函数在返回值时重复给定的操作:
import Control.Monad
import Control.Monad.Trans
import Control.Monad.Trans.Maybe
while :: (Monad m) => MaybeT m b -> m ()
while k = runMaybeT (forever k) >> return ()
一旦k
返回mzero
,循环停止。然后我们可以使用标准的MonadPlus
combinator在任何地方很好地中断循环:
main = while $ do
l <- lift getLine
guard $ l /= "quit"
lift $ putStrLn l
更新:也许最简单的解决方案是使用来自monad循环:
您可以在Control.Monad
main=interact$unlines中的时尝试。takeWhile(/=“退出”)。行
不使用
翻转
翻转函数是一种有趣的方式!
main = while $ mfilter (/= "quit") (lift getLine) >>= lift . putStrLn
isValid s | s /= "quit" = Just s
| otherwise = Nothing
main = whileJust_ (isValid `liftM` getLine) putStrLn