我的haskell代码有点问题:
import Prelude
hangman :: String -> IO ()
hangman [] = return ()
hangman s = do putStr ("Secret: " ++ text s ++ "n")
putStr "Enter a character: "
charr <- getChar
function s charr (text s)
function :: String -> Char -> String -> IO ()
function [] _ _ = return ()
function (a:bc) charr (g:jt) = do putStr ("Secret: " ++ (textBack (a:bc) charr (g:jt)) ++ "n")
putStr "Enter a character: "
charbaby <- getChar
putStr "n"
function (a:bc) charbaby (textBack (a:bc) charbaby (g:jt))
text :: String -> String
text [] = ""
text (x:ys) = "*" ++ text ys
textBack :: String -> Char -> String -> String
textBack [] _ _ = ""
textBack (a:bc) charr (g:jt) = if charr == a
then charr : textBack bc charr jt
else g : textBack bc charr jt
这是输出:
*Main> hangman "hello"
Secret: *****
Enter a character: h
Secret: h****
Enter a character:
Secret: h****
Enter a character: e
Secret: he***
Enter a character:
Secret: he***
Enter a character: l
Secret: hell*
Enter a character:
Secret: hell*
Enter a character: o
Secret: hello
Enter a character:
Secret: hello
Enter a character:
正如你所看到的,有些线路被多次调用,我不知道为什么。我希望你能帮助我:(
谢谢你,
Finn
我认为有两件事让你自己变得困难:
- 您在
hangman
和function
中复制了逻辑。这使得事情很难保持同步;以及 - 您使用了不必要的模式匹配,使功能不那么优雅
对于真正的问题,我认为这是由于使用了 ENTER因此,您最好使用 因此,这将检索一个猜测: 您可以将getChar
:getChar
从stdin中获取一个字符,如果您编写例如H和getLine
,然后只使用第一个字符,或者在用户写入多个字符时要求再次输入。例如:readGuess :: String -> Maybe Char
readGuess [x] = Just x
readGuess _ = Nothing
getGuess :: IO Char
getGuess = do
putStrLn "Enter a character:"
cs <- readGuess <$> getLine
case cs of
Just c-> pure c
Nothing -> putStrLn "Invalid guess" >> getGuess
Prelude> getGuess
Enter a character:
Invalid guess
Enter a character:
hello
Invalid guess
Enter a character:
foo
Invalid guess
Enter a character:
b
'b'
hangman
简化为:hangman :: String -> IO ()
hangman s = hangman' s (text s)
hangman' :: String -> String -> IO ()
hangman' sa sb
| sa == sb = putStrLn "You won"
| otherwise = do
putStr ("Secret: " ++ sb ++ "n")
g <- getGuess
hangman' sa (textBack sa g sb)