簡體   English   中英

如何在Haskell中將主:: IO()重寫為由一個主:: IO()組成的兩個函數

[英]How to rewrite in Haskell a main :: IO () to two functions consisting of one main :: IO()

我想通過拆分一些東西使它成為一個更簡單的主要功能。 但是,當我添加新功能maakNieuwSpel時,出現錯誤

 maakNieuwSpel :: Int -> String -> IO ()
 maakNieuwSpel aantal firstName= do let rijTegels = volleRijTegels
                                    let spelers = deSpelers aantal firstName 
                                    w <- spelSpelen rijTegels spelers 0
                                    putStrLn (w ++ "dit is waar ik mee bezig was in functie nieuwSpel")

當我主要用

    eindstand <- maakNieuwSpel (digitToInt aantalTegenspelers) firstName

它給了錯誤。

我嘗試並希望實現的另一件事是通過放置where函數來重寫main中的let函數。 我當時就是這樣想的

    eindstand <- spelSpelen rijTegels spelers 0 
            where rijTegels = volleRijTegels
                   spelers = deSpelers (digitToInt aantalTegenspelers) firstName  

但是然后它說“解析輸入'='時的錯誤也許您需要在'do'塊中添加'let'嗎?”

這是我的代碼的一部分。 我想它將為您提供我正在做的事情的足夠洞察力。

 data Dobbelsteen = Steen Char -- now its values can be specified
                deriving (Show, Eq)  
 data Tegel = Teg Int Int 
          deriving (Show, Eq) 
 data Speler = Spel Tactiek Spelersstapel String
 type Tactiek = ([Dobbelsteen]  -> [Dobbelsteen] -> IO [Dobbelsteen], [Dobbelsteen]  -> Int -> IO Bool)
  type Spelersstapel = [Tegel]



 main :: IO ()  
 main = do putStrLn ("Hoi! Je speelt regenwormen. Wat is je naam?")
           firstName <- getLine  
           putStrLn ("Beste "++ firstName ++ ", je speelt tegen twee computertegenstanders. Ze heten Lap en Top.")
           putStr "Tegen hoeveel computertegenstanders wil u spelen? (Dit spel is voor 2 tot 8 personen) "
           aantalTegenspelers <- getChar
           let rijTegels = volleRijTegels
           let spelers = deSpelers (digitToInt aantalTegenspelers) firstName 
           eindstand <- {-maakNieuwSpel (digitToInt aantalTegenspelers) firstName-} spelSpelen rijTegels spelers 0
           putStrLn ("Het spel is afgelopen. De eindstand is " ++ eindstand)


spelSpelen :: [Tegel]  -> [Speler]  -> Int -> IO String -- de RijTegels, de spelers en degene die gaat spelen (int)
spelSpelen []        spelers spelerNr = do return (show (bepaalEindStand spelers))
spelSpelen rijTegels spelers spelerNr = do let Spel tactiek stapel naam = (spelers !! spelerNr)
                                           putStrLn ("Deze speler is nu aan de beurt: " ++ naam)
                                           score <- beurt tactiek (\x -> elem x (bepaalGeldigeScore spelers naam rijTegels))
                                           let rijTegelsNieuw = pakTegelAlsMogelijk rijTegels score
                                           let rijTegelsTeruggelegdNieuw = legTegelTerug spelers rijTegels score
                                           let spelersAfgepaktNieuw = pakTegelAf spelers score
                                           let spelersNieuw = voegTegelToeAanSpelerVanStapel spelersAfgepaktNieuw score naam rijTegelsTeruggelegdNieuw
                                           putStrLn ("De beurt van speler " ++ naam ++ " is nu afgelopen.")
                                           printStatus rijTegelsNieuw spelersNieuw
                                           spelSpelen rijTegelsNieuw spelersNieuw ( (spelerNr+1) `mod` 3)  


 volleRijTegels :: [Tegel] -- deze functie maakt de rij tegels van 21 tot 36.
 volleRijTegels = zipWith Teg [21..36] (replicate 4 1 ++ replicate 4 2 ++ replicate 4 3 ++ replicate 4 4)

 deSpelers :: Int -> String -> [Speler]
 deSpelers aantalTegenspelers firstName = do [Spel computerTactiek [] firstName, Spel computerTactiek [] "Lap", Spel computerTactiek [] "Top"]

您已正確完成所有操作; 縮進只是一個小問題。 嘗試dedenting的最后一行main ,就像這樣:

 main :: IO ()  
 main = do
      -- ... stuff ...
      eindstand <- {-maakNieuwSpel (digitToInt aantalTegenspelers) firstName-} spelSpelen rijTegels spelers 0
      putStrLn ("Het spel is afgelopen. De eindstand is " ++ eindstand)

看看在我的版本中, eindstandputStrLn有多少空格? 在您的版本中, putStrLn有多余的空間,導致GHC認為這是spelSpelen的參數。 如果您刪除了多余的空間,它將開始工作。

該問答可能更適合codereview.stackexchange.com

除了基本的縮進問題之外,想要將main分成多個部分也是一個好主意。

另外,您將要嘗試使某些部分變為非IO 例如,應該有可能在不接觸任何IO情況下解決所有游戲邏輯。 如果您的游戲邏輯中沒有任何getLineputStrLn調用,則它更容易測試,並且錯誤源少,因為輸入驗證可以分為獨立的部分。

至於沒有嵌入IO的游戲邏輯的樣子,我不能說,因為游戲邏輯是用荷蘭語寫的? 如果您將此代碼翻譯成英語,或將代碼的翻譯副本重新提交到codereview.stackexchange.com,則有人可能會建議如何執行此操作。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM