2016-04-30 100 views
2

我試圖讓我的Cell類型爲Show typeclass的成員。 show a線路有問題。如何確保a在該展示櫃中是Char?我希望這些陳述的順序只是讓它能夠處理它,但那並不是。Typeclass聲明類型不匹配

data Cell = Solid | Blank | Char 

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

main = print $ show Solid 

回答

2
data Cell = Solid | Blank | Char 

這是一個tagged union,這意味着SolidBlankChar是構造函數的名稱,而不是類型。例如,Char :: Cell

我懷疑你的意思是下面這樣的:

data CellType = CellConstructor Char 

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

例子:

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

如果只有一個構造函數,那麼通常給類型和構造函數一個相同的名字。

data Cell = Cell Char 

如果只有一個構造函數只有一個字段,那麼習慣使用newtype。

newtype Cell = Cell Char 
1

Char這裏不是型號Char;它是一個名爲Char的新數據構造函數。如果你想CellSolidBlank,或Char類型的值,則需要

data Cell = Solid | Blank | Char Char 

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

一些例子:

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

看那類型類Show的定義,主要是在show功能:

class Show a where 
    show  :: a -> String 

現在,你的實例爲你的Cell類型滿足它?第一種情況,show Solid = "X"確實 - SolidCell"X"是一個字符串。第二種情況也是如此。但是第三種情況是什麼?您將其定義爲show a = [a],因此類型簽名是Cell -> [Cell][Cell]不是String。因此你得到一個類型不匹配。

3

您不能確定aChar類型的值,因爲那根本不可能是這樣。 a將始終是類型爲Cell的值,具體而言,它將是值Char(它與Char類型無關)。

你似乎想要的是讓Cell的第三個構造函數包含Char類型的值。要做到這一點你的構造需要一個參數:

data Cell = Solid | Blank | CharCell Char 

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

如果構造CharCell已使用和a將要使用的值作爲CharCellCharCell a情況相匹配的參數(因而有型Char,因爲這是CharCell「 s參數類型)。