2
votes

I have a compilation problem where the expected type is sometimes {} and sometimes Game, depending on how I change the annotation for the function stepGame.

data State = Start | Play | End

type Game = { state:State, player1:Snake, player2:Snake, player3:Snake,
              player4:Snake }

defaultGame : Game
defaultGame = -- stuff (returns Game type with default values)

stepGame : Input -> Game -> Game 
stepGame {space,delta,so1,so2,so3,so4}
         ({state,p1,p2,p3,p4} as game) =
    let state' = -- stuff
        p1' = -- stuff
        p2' = -- stuff
        p3' = -- stuff
        p4' = -- stuff
    in  case state' of
            Start -> if space then defaultGame else game
            Play  -> { game | state <- state'
                            , p1    <- p1'
                            , p2    <- p2'
                            , p3    <- p3'
                            , p4    <- p4' }
            End   -> if space then defaultGame
                     else { game | state <- state' }

What happens to the variables and what the input is exactly doesn't really matter. Running this will give me:

Expected Type: {}
  Actual Type: Main.Game

Both defaultGame and game are type Game, so I found this weird. If I change the stepGame annotation from:

stepGame : Input -> Game -> Game 

to:

stepGame : Input -> Game -> Int

it will give the following compile error:

Expected Type: Int
  Actual Type: Main.Game

This is expected and correct. The return values are of type Game but in my annotation I expect Int. Examining this and the prior compile error I deducted the return values are correct but somehow it was expecting the function to return nothing, while it should be expecting a Game type return value.

So I tried to change the annotation to:

stepGame : Input -> Game -> Game -> Int

This correctly gives:

Expected Type: Main.Game -> Int
  Actual Type: Main.Game

So my question is, why does it not expect a Game type as the function return value when I use:

stepGame : Input -> Game -> Game
1
Write an answer to your own question and make that the accepted answer - Apanatshka
@Apanatshka That seems a bit of a narcissistic thing to do. :P Thanks for your help on my previous question btw! - Babyburger
Actually it's encouraged by stackoverflow: stackoverflow.com/help/self-answer - Apanatshka

1 Answers

1
votes

The type of Game is expecting variables state, player1, player2, player3 and player4. In the arguments of stepGame I noted them p1,p2,p3 and p4 for short. This is not allowed. So:

stepGame : Input -> Game -> Game 
stepGame {space,delta,so1,so2,so3,so4}
         ({state,player1,player2,player3,player4} as game) = -- stuff

fixed it.