我是Haskell的新手,我必须为大学做一个项目。我在使用案例陈述时遇到了麻烦。
case words command of
("Highlight":_) -> putStrLn ("Highlight | \x1b[32m\x1b[107m" ++ show (aLine) ++ "\x1b[0m")
("InsertChar":_) -> putStrLn ("Insert Char | " ++ show (insertChar aLine))
("DelCharRight":_) -> putStrLn ("Delete Char Right | " ++ show (delCharRight aLine))
("DelCharLeft":_) -> putStrLn ("Delete Char Left | " ++ show (delCharLeft aLine))
("CharRight":_) -> putStrLn ("Move Char Right | " ++ show (charRight aLine))
("CharLeft":_) -> putStrLn ("Move Char Left | " ++ show (charLeft aLine))
("WordRight":_) -> putStrLn ("Move Word Right | " ++ show (wordRight aLine))
("WordLeft":_) -> putStrLn ("Move Word Left | " ++ show (wordLeft aLine))
("EndLineRight":_) -> putStrLn ("End Line Right | " ++ show (endLineRight aLine))
("EndLineLeft":_) -> putStrLn ("End Line Left | " ++ show (endLineLeft aLine))
("HighlightRight":_) -> putStrLn ("Highlight Right | " ++ show (highlightRight aLine))
("HighlightLeft":_) -> putStrLn ("Highlight Left | " ++ show (highlightLeft aLine))
("HighlightWordRight":_) -> putStrLn ("Highlight Word Right | " ++ show (highlightWordRight aLine))
("HighlightWordLeft":_) -> putStrLn ("Highlight Word Left | " ++ show (highlightWordLeft aLine))
("Copy":_) -> putStrLn ("Copy | " ++ show (copy aLine))
("Cut":_) -> putStrLn ("Cut | " ++ show (cut aLine))
("Paste":_) -> putStrLn ("Paste | " ++ show (paste aLine))
("Destroy":_) -> putStrLn ("Destroy | " ++ show (destroy aLine))
("ClearScreen":_) -> clearScreen
("Save":_) -> writeFile savePath (command ++ " | " ++ show (save aLine))
_ -> putStrLn "Error: Incorrect Command"
return command
如何在同一行命令中添加更多代码?我想要这样的东西:
("DelCharRight":_) -> putStrLn ("Delete Char Right | " ++ show (delCharRight aLine) let bLine = delCharRight aLine let aLine = bLine
这基本上允许我在每个命令后覆盖一行,这样我就可以继续输入命令来编辑文本行。
麻烦是案例陈述不允许我使用'让'。
我为可怕的代码和解释道歉!
答案 0 :(得分:1)
要回答您的确切问题,您只需在do
->
即可
("DelCharRight":_) -> do
putStrLn ("Delete Char Right | " ++ show (delCharRight aLine)
let bLine = delCharRight aLine
let aLine = bLine
但它没有帮助--Haskell中的let
声明无法做到你想要的。作为一般规则,您不能在Haskell中改变数据。 aLine
只会有一个值。如果您有命令式编程的背景知识,您可能会查看以下代码并(错误地)推断出某种突变正在发生,x
会改变它的值。但所有这些都是阴影(尝试let x = x + x
),看看它是做什么的。
someFunc :: IO ()
someFunc = do
let x = 3
let x = 5
print x
那就是说,因为你在IO
,你可以获得突变。 IORefs(在Data.IORef中找到)是可以使用的可变引用。
someFunc' :: IO ()
someFunc' = do
x <- newIORef 3
writeIORef x 5
readIORef x >>= print
但我建议不要使用IORef
。写一个单独的函数来返回更改后的值,然后将结果作为输入提供给下一个调用,这是更惯用的Haskell。这是一个简单&#34;计数器&#34;。
main :: IO ()
main = do
commandLine <- getLine
let commands = words commandLine
counter <- runCounter commands 0
print counter
-- There is a higher-order functions (foldM) that we
-- could use instead of this function
-- but we'll avoid it for the sake of clarity
runCounter :: [String] -> Int -> IO Int
runCounter [] counter = return counter
runCounter (cmd:cmds) counter = do
newCounter <- updateCounter cmd counter
runCounter cmds counter
updateCounter :: String -> Int -> IO Int
updateCounter command counter = case command of
"UP" -> do
putStrLn "Incrementing counter"
return (counter + 1)
"DOWN" -> do
putStrLn "Decrementing counter"
return (counter - 1)
答案 1 :(得分:0)
选项1:添加do
case ... of
...
("DelCharRight":_) -> do
let bLine = delCharRight aLine
aLine = bLine
putStrLn (...)
选项2:使用let .. in ..
case ... of
...
("DelCharRight":_) ->
let bLine = delCharRight aLine
aLine = bLine
in putStrLn (...)
选项2更为通用,因为即使我们不在某个monad中工作(我们在IO
内部也是如此,所以do
也是可能的)。