简体   繁体   English

类型类声明类型不匹配

[英]Typeclass declaration type mismatch

I am trying to make my Cell type a member of the Show typeclass. 我试图使我的Cell类型成为Show typeclass的成员。 The show a line is problematic. show a线有问题。 How do I make sure that the a is a Char in that show case? 在该展示柜中,如何确定a是一个Char I was hoping the ordering of the statements would just let fallthrough handle it, but that doesn't do it. 我希望语句的顺序只会让fallthrough处理它,但是那没有做到。

data Cell = Solid | Blank | Char

instance Show (Cell) where
    show Solid = "X"
    show Blank  = "_";
    show a = [a]

main = print $ show Solid

You can't make sure that a is a value of type Char because that simply can't be the case. 您不能确保aChar类型的值,因为事实并非如此。 a will always be a value of type Cell , specifically it will be the value Char (which has no relation to the type Char ). a将始终是Cell类型的值,特别是它将是Char值(与Char类型无关)。

What you seem to want is to have Cell 's third constructor contain a value of type Char . 您似乎想要的是让Cell的第三个构造函数包含Char类型的值。 To do that your constructor needs a parameter: 为此,您的构造函数需要一个参数:

data Cell = Solid | Blank | CharCell Char

instance Show (Cell) where
    show Solid = "X"
    show Blank  = "_"
    show (CharCell a) = [a]

The CharCell a case matches if the constructor CharCell has been used and a will be the value used as CharCell 's parameter (and thus have type Char as that is CharCell 's parameter type). 所述CharCell a情况下,如果匹配的构造CharCell已使用的和a将被用作值CharCell的参数(并且因此具有式Char ,因为这是CharCell的参数类型)。

data Cell = Solid | Blank | Char

This is a tagged union , which means Solid , Blank , and Char are constructor names, not types. 这是一个标记的union ,这意味着SolidBlankChar是构造函数名称,而不是类型。 For example, Char :: Cell . 例如, Char :: Cell

I suspect what you meant was something such as this: 我怀疑您的意思是这样的:

data CellType = CellConstructor Char

instance Show CellType where
  show (CellConstructor c) = [c]

Examples: 例子:

  • CellConstructor 'X' :: CellType
  • CellConstructor '_' :: CellType
  • CellConstructor 'a' :: CellType

It is customary to give the type and constructor the same name if there is only one constructor. 如果只有一个构造函数,通常给类型和构造函数相同的名称。

data Cell = Cell Char

If there is only one constructor with only one field then it is customary to use a newtype. 如果只有一个构造函数只有一个字段,则习惯上使用新类型。

newtype Cell = Cell Char 

Char here is not the type Char ; Char这里就不类型Char ; it is a new data constructor named Char . 它是一个名为Char的新数据构造函数。 If you want Cell to be Solid , Blank , or a value of type Char , you need 如果要让CellSolidBlankChar类型的值,则需要

data Cell = Solid | Blank | Char Char

instance Show Cel where
    show Solid = "X"
    show Blank = "_"
    show (Char c) = [c]

Some examples: 一些例子:

> show Solid
"X"
> show Blank
"_"
> show (Char '4')
"4"

Look at the definition of the typeclass Show , mainly at the show function: 查看type类Show的定义,主要是show函数:

class Show a where
    show      :: a   -> String

Now, does your instance for your Cell type satisfy it? 现在,您对Cell类型的实例满足吗? The first case, show Solid = "X" does - Solid is Cell and "X" is a String. 第一种情况, show Solid = "X"可以SolidCell"X"是字符串。 The same goes for the second case. 第二种情况也是如此。 But what is the third case? 但是第三种情况是什么? You defined it as show a = [a] so the type signature is Cell -> [Cell] and [Cell] is not a String . 您将其定义为show a = [a]因此类型签名为Cell -> [Cell]并且[Cell]不是String Therefore you get a type mismatch. 因此,您会遇到类型不匹配的情况。

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

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