简体   繁体   English

类型未正确编写且不接受 Eq 约束?

[英]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:如果我插入 Eq 以便movePlayer :: Eq a => Play -> Maze -> Player -> Player它会给我以下错误:

    • 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. Sooo 我对这种语言和编程很陌生,我不知道为什么会发生这种情况。 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.您尚未指定编译器检查Orientation是否相等的方法。 In most cases you can use deriving Eq like you've done with Show in other places.在大多数情况下,您可以像在其他地方使用Show那样使用deriving Eq ( deriving Eq only works if all of the types it contains also have Eq instances. Otherwise, you'll need to explicitly define an instance .) (仅当deriving Eq包含的所有类型也具有Eq实例时, deriving Eq才有效。否则,您需要显式定义一个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.当你说Eq a => ,这告诉编译器你想在你定义的任何函数内的a上使用Eq函数。 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 .这只是意味着编译器错误应该发生在函数调用发生的地方,而不是在您尝试使用==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 => . Eq a =>只是让编译器和代码阅读器更清楚你对=>右侧使用的某种类型a期望。 It doesn't actually provide the Eq property.它实际上并不提供Eq属性。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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