用 guards [Haskell] 检查字符串的每个字符
Check every character of a string with guards [Haskell]
我在尝试使用 Haskell 时遇到问题。我想读取一串数字并在看到字符时打印各种消息。
import System.Environment
import System.Exit
import Data.List
import Control.Monad
test_parse:: [Char] -> IO ()
test_parse [] = putStrLn "\n"
test_parse (a:b:c:xs)
| a == '1' && b == '2' && c == '3' = putStrLn ("True")
| a == '2' && b == '3' && c == '4' = putStrLn ("False")
| a == '4' && b == '5' && c == '6' = putStrLn ("maybe")
| otherwise = test_parse (b:c:xs)
main = do
let numbers = "123456"
let loop = do
goGlenn <- getLine
test_parse numbers
putStrLn goGlenn
when (goGlenn /= "start") loop
loop
putStrLn "ok"
问题是这样的。我想打印 "True\nFalse\nMaybe\n" 但我只打印 "True\n"。我知道我的问题是,当警卫采取行动时,它会离开功能。但是我不知道如何在不离开 'test_parse
.
的情况下检查整个字符串
如果有人有想法,谢谢。
您想检查每个后缀,而不考虑前缀的结果。一个例子:
-- output a string based on the first 3 characters of the input
classify :: String -> IO ()
classify xs = case take 3 xs of
"123" -> putStrLn "True"
"234" -> putStrLn "False"
"456" -> putStrLn "maybe"
otherwise -> return ()
-- call classify repeatedly on different suffixes of the input
test_parse :: String -> IO ()
test_parse [] = return ()
test_parse all@(_:xs) = do
classify all
test_parse xs
为了说明 chepner 关于制作 classify
return 列表 String
而不是 I/O:
的观点
import Data.List (tails)
classify :: String -> [String]
classify s = case take 3 s of
"123" -> return "True"
"234" -> return "False"
"456" -> return "maybe"
otherwise -> mempty
classifyAll :: String -> [String]
classifyAll s = tails s >>= classify
main :: IO ()
main = interact (unlines . classifyAll)
运行这个,
$ stack ghc classify.hs
$ echo 123456 | ./classify
True
False
maybe
I can't choose if i want to put a \n after the print or not.
Basically, it's working, but can we delete \n if we want?
如果你想用换行符以外的东西分隔,
import Data.List (intercalate, tails)
...
main :: IO ()
main = interact ((++ "\n") . intercalate ", " . classifyAll)
运行这个,
$ echo 123456 | ./classify
True, False, maybe
拆分解析和打印的代码还可以使您的代码更易于测试。例如
spec_classify :: Spec
spec_classify =
describe "classify" $
it "classifies 123, 234 and 456" $
classifyAll "123456" `shouldBe` ["True", "False", "maybe"]
测试这个,
$ stack ghci classify.hs
> hspec spec_classify
classify
classifies 123, 234 and 456
Finished in 0.0005 seconds
1 example, 0 failures
我在尝试使用 Haskell 时遇到问题。我想读取一串数字并在看到字符时打印各种消息。
import System.Environment
import System.Exit
import Data.List
import Control.Monad
test_parse:: [Char] -> IO ()
test_parse [] = putStrLn "\n"
test_parse (a:b:c:xs)
| a == '1' && b == '2' && c == '3' = putStrLn ("True")
| a == '2' && b == '3' && c == '4' = putStrLn ("False")
| a == '4' && b == '5' && c == '6' = putStrLn ("maybe")
| otherwise = test_parse (b:c:xs)
main = do
let numbers = "123456"
let loop = do
goGlenn <- getLine
test_parse numbers
putStrLn goGlenn
when (goGlenn /= "start") loop
loop
putStrLn "ok"
问题是这样的。我想打印 "True\nFalse\nMaybe\n" 但我只打印 "True\n"。我知道我的问题是,当警卫采取行动时,它会离开功能。但是我不知道如何在不离开 'test_parse
.
如果有人有想法,谢谢。
您想检查每个后缀,而不考虑前缀的结果。一个例子:
-- output a string based on the first 3 characters of the input
classify :: String -> IO ()
classify xs = case take 3 xs of
"123" -> putStrLn "True"
"234" -> putStrLn "False"
"456" -> putStrLn "maybe"
otherwise -> return ()
-- call classify repeatedly on different suffixes of the input
test_parse :: String -> IO ()
test_parse [] = return ()
test_parse all@(_:xs) = do
classify all
test_parse xs
为了说明 chepner 关于制作 classify
return 列表 String
而不是 I/O:
import Data.List (tails)
classify :: String -> [String]
classify s = case take 3 s of
"123" -> return "True"
"234" -> return "False"
"456" -> return "maybe"
otherwise -> mempty
classifyAll :: String -> [String]
classifyAll s = tails s >>= classify
main :: IO ()
main = interact (unlines . classifyAll)
运行这个,
$ stack ghc classify.hs
$ echo 123456 | ./classify
True
False
maybe
I can't choose if i want to put a \n after the print or not.
Basically, it's working, but can we delete \n if we want?
如果你想用换行符以外的东西分隔,
import Data.List (intercalate, tails)
...
main :: IO ()
main = interact ((++ "\n") . intercalate ", " . classifyAll)
运行这个,
$ echo 123456 | ./classify
True, False, maybe
拆分解析和打印的代码还可以使您的代码更易于测试。例如
spec_classify :: Spec
spec_classify =
describe "classify" $
it "classifies 123, 234 and 456" $
classifyAll "123456" `shouldBe` ["True", "False", "maybe"]
测试这个,
$ stack ghci classify.hs
> hspec spec_classify
classify
classifies 123, 234 and 456
Finished in 0.0005 seconds
1 example, 0 failures