Как переписать в Haskell main :: IO () для двух функций, состоящих из одного main :: IO () - PullRequest
0 голосов
/ 04 апреля 2019

Я хочу сделать это более простой основной функцией, разделив некоторые вещи. Но когда я добавляю новую функцию 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

это дало ошибки.

ДРУГОЕ, чего я пытался достичь, - переписать функции let в main, поместив функцию where. Примерно так я и думал

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

Но тогда он говорит "ошибка разбора на входе‘ = ’Возможно, вам нужен блок let в блоке do?"

Это часть моего кода. Я полагаю, это даст вам достаточное представление о том, что я делаю.

 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"]

Ответы [ 2 ]

2 голосов
/ 04 апреля 2019

Вы все сделали правильно;Есть только небольшая проблема с отступом.Попробуйте сделать отступ в последней строке main, например:

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

Посмотрите, как в моей версии eindstand и putStrLn имеют одинаковое количество пробелов перед ними?В вашей версии перед putStrLn стоит дополнительный пробел, что заставляет GHC думать, что это параметр spelSpelen.Он должен начать работать, если вы удалите это дополнительное пространство.

1 голос
/ 04 апреля 2019

Эти вопросы и ответы лучше подходят для codereview.stackexchange.com .

Помимо основных проблем с отступами, желательно разделить ваш main на несколько частей.

Кроме того, вы захотите попробовать сделать некоторые из этих частей не IO. Например, должна быть возможность обратиться к всей игровой логике, не касаясь какой-либо IO. Если в вашей игровой логике нет вызовов getLine или putStrLn, это проще проверить, и источников ошибок немного, поскольку проверка входных данных может быть разделена на отдельные части.

Что касается того, как может выглядеть игровая логика без IO, я не могу сказать, потому что игровая логика написана на каком, голландском? Если вы переведете этот код на английский или повторно отправите переведенную копию кода на codereview.stackexchange.com, кто-то может подсказать, как это сделать.

...