繁体   English   中英

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

[英]Types not correctly written and Eq constraint not accepted?

如果有人可以请帮助我! 这是我为类型和数据类型分离的模块

 -- = 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

这是我想创建的一个函数示例,它接收一个播放、一个迷宫和一个播放器,并在播放后返回一个值改变或不改变的播放器

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))

它不断给我这个错误:

  • 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))

如果我插入 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 我对这种语言和编程很陌生,我不知道为什么会发生这种情况。 也许我没有正确放置类型或值构造函数,这就是我在此处添加类型代码的原因。 非常感谢!

您尚未指定编译器检查Orientation是否相等的方法。 在大多数情况下,您可以像在其他地方使用Show那样使用deriving Eq (仅当deriving Eq包含的所有类型也具有Eq实例时, deriving Eq才有效。否则,您需要显式定义一个instance 。)

当你说Eq a => ,这告诉编译器你想在你定义的任何函数内的a上使用Eq函数。 这只是意味着编译器错误应该发生在函数调用发生的地方,而不是在您尝试使用==a的特定位置。

Eq a =>只是让编译器和代码阅读器更清楚你对=>右侧使用的某种类型a期望。 它实际上并不提供Eq属性。

暂无
暂无

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

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