简体   繁体   中英

Types not correctly written and Eq constraint not accepted?

If someone can please help me! This is the module I have separated for type and data type

 -- = Tipos e construtores de tipos 
    
    -- | Tipo __Maze__, lista de Corredores
    --
    type Maze = [Corridor]
    
    -- | Tipo __Corridor__, lista de peças
    --
    type Corridor = [Piece]
    
    -- | Construtor de tipo para __Piece__, podemos ter comida, jogador, empty e wall
    --
    data Piece = Food FoodType | PacPlayer Player| Empty | Wall
    
    -- | Construtor de tipo para __FoodType__, podemos ter __grande__ /(responsável pelo Mega)/ ou __pequena__
    data FoodType = Big | Little
    
    -- | Caracteres relativos às peças
    --
    instance Show Piece where
        show (Food Big) = "o"
        show (Food Little) = "."
        show (Wall) = "#"
        show (Empty) = " "
    
    -- | Construtor de tipo para o jogador, podendo ser __Pacman__ ou __Ghost__
    --
    data Player = Pacman PacState | Ghost GhoState
    
    -- | Construtor de tipo para o __Estado do Pacman__, onde tem-se o /estado_do_jogador/, /tempo_Mega/, se a boca está /aberta_ou_fechada/ e o /modo/ (morrendo, mega ou normal)
    --
    data PacState = PacState 
        {   
            pacState :: PlayerState
        ,   timeMega :: Double
        ,   openClosed :: Mouth
        ,   pacmanMode :: PacMode
        
        }
    
    -- | Construtor de tipo para o __Estado do Ghost__, onde tem-se o /estado do jogador/ e o /modo/ (morto ou vivo)
    --
    data GhoState = GhoState 
        {
            ghostState :: PlayerState
        ,   ghostMode :: GhostMode
        }
    
    -- | Tipo das __Coordenadas__
    --
    type Coords = (Int,Int)
    
    -- | Tipo do Estado do Jogador, em ordem : (/ID/, /Coordenadas/, /Velocidade/, /Orientação/, /Pontuação/, /Vidas restantes/)
    --
    type PlayerState = (Int, Coords, Double, Orientation, Int, Int)
    
    -- | Construtor de tipo para a __Boca__ do Pacman, pode estar /aberta/ ou /fechada/
    --
    data Mouth = Open | Closed 
    
    -- | Construtor de tipo para o __Pacmode__
    --
    data PacMode = Dying | Mega | Normal deriving Show 
    
    -- | Construtor de tipo para o __Ghostmode__
    --
    data GhostMode = Dead | Alive deriving Show
    
    -- | Construtor de tipo para o Estado do jogo, no qual há o /labirinto/, /estado_do_jogador/ e o /nível/
    --
    data State = State 
       {
           maze :: Maze
       ,   playersState :: [Player]
       ,   level :: Int
       }
    
    -- | Construtor de tipo para __Play__ no qual dá-se o /ID/ do jogador e /Orientação/ pretendida 
    --
    data Play = Move Int Orientation
    
    -- | Construtor de tipo para __Orientação__ no qual há /Left/, /Right/, /Up/ e /Down/
    data Orientation = L | R | U | D

And this is the sample of a function that I would like to create which receives a play, a maze and a player and returns a player with its values changed or not after the play

movePlayer :: Play -> Maze -> Player -> Player
movePlayer (Move j o) m (Pacman (PacState (id, (a,b), v, orientation, points, lifes) timeMega openClosed pacmanMode)) =  if o == orientation then (Pacman (PacState (j, (a+1,b), v, o, points, lifes) timeMega openClosed pacmanMode)) else (Pacman (PacState (j, (a,b), v, o, points, lifes) timeMega openClosed pacmanMode))

And it keeps giving me this error:

  • No instance for (Eq Orientation) arising from a use of ‘==’
    • In the expression: o == orientation
      In the expression:
        if o == orientation then
            (Pacman
               (PacState
                  (j, (a + 1, b), v, o, points, lifes)
                  timeMega
                  openClosed
                  pacmanMode))
        else
            (Pacman
               (PacState
                  (j, (a, b), v, o, points, lifes) timeMega openClosed pacmanMode))
      In an equation for ‘movePlayer’:
          movePlayer
            (Move j o)
            m
            (Pacman (PacState (id, (a, b), v, orientation, points, lifes)
                              timeMega
                              openClosed
                              pacmanMode))
            = if o == orientation then
                  (Pacman
                     (PacState
                        (j, (a + 1, b), v, o, points, lifes)
                        timeMega
                        openClosed
                        pacmanMode))
              else
                  (Pacman
                     (PacState
                        (j, (a, b), v, o, points, lifes) timeMega openClosed pacmanMode))
  |
7 | movePlayer (Move j o) m (Pacman (PacState (id, (a,b), v, orientation, points, lifes) timeMega openClosed pacmanMode)) =  if o == orientation then (Pacman (PacState (j, (a+1,b), v, o, points, lifes) timeMega openClosed pacmanMode)) else (Pacman (PacState (j, (a,b), v, o, points, lifes) timeMega openClosed pacmanMode))

If I insert Eq in order to have movePlayer :: Eq a => Play -> Maze -> Player -> Player it then gives me the following error:

    • Could not deduce (Eq a0)
      from the context: Eq a
        bound by the type signature for:
                   movePlayer :: forall a. Eq a => Play -> Maze -> Player -> Player
        at Teste2.hs:6:15-54
      The type variable ‘a0’ is ambiguous
    • In the ambiguity check for ‘movePlayer’
      To defer the ambiguity check to use sites, enable AllowAmbiguousTypes
      In the type signature:
        movePlayer :: Eq a => Play -> Maze -> Player -> Player
  |
6 | movePlayer :: Eq a => Play -> Maze -> Player -> Player
  |               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Failed, two modules loaded.

Sooo I am very new to this language and programming in general and I have no idea why it is happening. Maybe I am not putting the types or values constructors correctly which is why I added the code for the types here. Thank you so much!

You haven't specified a way for the compiler to check Orientation for equality. In most cases you can use deriving Eq like you've done with Show in other places. ( deriving Eq only works if all of the types it contains also have Eq instances. Otherwise, you'll need to explicitly define an instance .)

When you say Eq a => , this tells the compiler that you want to use Eq functions on a within whatever function you're defining. This just means that the compiler error should occur where the function call happens, rather than in the particular spot that you try to use == with a .

Eq a => just makes it clearer to the compiler and to the code reader what you expect of some type a used on the right side of => . It doesn't actually provide the Eq property.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM