Я пытаюсь изучить Haskell, создав простую игру в шахматы. Однако у меня возникли проблемы с определением функции, представляющей квадрат доски.
import Data.Char
type Board = [[Square]]
type Square = Maybe Piece
data Piece = Piece PieceColor PieceType deriving (Show, Eq)
data PieceColor = White | Black deriving (Show, Eq)
data PieceType = King | Queen | Rook | Bishop | Knight | Pawn deriving (Show, Eq)
...
displaySquare :: Square -> Char
displaySquare n
| n == Nothing = ' '
| n == Just (Piece White _) = displaySquare' n
| otherwise = toLower (displaySquare' n)
where
displaySquare' (Just (Piece _ King)) = 'K'
displaySquare' (Just (Piece _ Queen)) = 'Q'
displaySquare' (Just (Piece _ Rook)) = 'R'
displaySquare' (Just (Piece _ Bishop)) = 'B'
displaySquare' (Just (Piece _ Knight)) = 'N'
displaySquare' (Just (Piece _ Pawn)) = 'P'
Попытка запустить GHCI возвращает следующую ошибку:
Chess.hs:21:30:
Found hole ‘_’ with type: PieceType
Relevant bindings include
displaySquare' :: Maybe Piece -> Char (bound at Chess.hs:24:13)
n :: Square (bound at Chess.hs:19:15)
displaySquare :: Square -> Char (bound at Chess.hs:19:1)
In the second argument of ‘Piece’, namely ‘_’
In the first argument of ‘Just’, namely ‘(Piece White _)’
In the second argument of ‘(==)’, namely ‘Just (Piece White _)’
Failed, modules loaded: none.
Я не совсем уверен, что ошибка пытается сказать мне. Если бы мне пришлось угадывать, я бы сказал, что проблема заключается в определении поля данных как дыры '_', поскольку это означает, что функция может принимать любой тип в качестве поля данных, что явно противоречит заданной сигнатуре типа. Верно ли мое предположение и как мне его решить?
_
) в выражении, что обычно приводило к ошибке. Однако_
теперь также является допустимым выражением, поэтому компиляция предположила, что вы знаете, что делаете, и намеренно поместила туда_
. В синтаксисе выражений это называется типизированной дырой — в основном, это используется для программирования, ориентированного на тип, поскольку компилятор выдает всю информацию о типе вокруг этой привязки. Компилятор, вероятно, должен распознавать типизированные дыры только в том случае, если они включены... в противном случае он должен выдавать ошибку синтаксического анализа/синтаксиса, чтобы избежать подобной путаницы. - person user2407038   schedule 14.11.2015