2016-04-30 22 views
2

Ich versuche, meinen Cell Typ zu einem Mitglied der Show Typklasse zu machen. Die show a Linie ist problematisch. Wie stelle ich sicher, dass der a ein Char in diesem Showfall ist? Ich hatte gehofft, die Reihenfolge der Anweisungen würde Fallfall einfach damit umgehen lassen, aber das tut es nicht.Typenklasse Deklarationstyp stimmt nicht überein

data Cell = Solid | Blank | Char 

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

main = print $ show Solid 

Antwort

2
data Cell = Solid | Blank | Char 

Dies ist ein tagged union, was bedeutet, Solid, Blank und Char sind Konstruktor Namen, keine Typen. Zum Beispiel Char :: Cell.

Ich vermute, was Sie meinten, so etwas wie das war:

data CellType = CellConstructor Char 

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

Beispiele:

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

Es ist üblich, Typ und Konstruktor den gleichen Namen zu geben, wenn nur ein Konstruktor vorhanden ist.

data Cell = Cell Char 

Wenn es nur einen Konstruktor mit nur einem Feld gibt, ist es üblich, einen neuen Typ zu verwenden.

newtype Cell = Cell Char 
1

Char hier ist nicht der Typ Char; Es ist ein neuer Datenkonstruktor mit dem Namen Char. Wenn Sie Cell wollen Solid, Blank oder ein Wert vom Typ sein Char, müssen Sie

data Cell = Solid | Blank | Char Char 

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

Einige Beispiele:

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

Blick auf die Definition des typeclass Show, vor allem an der show Funktion :

class Show a where 
    show  :: a -> String 

Jetzt ist Ihre Instanz für Ihre Cell typ befriedigen? Der erste Fall, show Solid = "X" ist - Solid ist Cell und "X" ist ein String. Das gleiche gilt für den zweiten Fall. Aber was ist der dritte Fall? Sie haben es als show a = [a] definiert, so dass die Signatur des Typs Cell -> [Cell] und [Cell] kein String ist. Daher erhalten Sie einen Typenkonflikt.

3

Sie können nicht sicherstellen, dass a ein Wert vom Typ Char ist, weil das einfach nicht der Fall sein kann. a wird immer ein Wert vom Typ Cell sein, speziell wird es der Wert Char sein (der keine Beziehung zum Typ Char hat).

Was Sie scheinen zu wollen ist Cell dritten Konstruktor enthalten einen Wert des Typs Char. Um das zu tun Konstruktor einen Parameter benötigt:

data Cell = Solid | Blank | CharCell Char 

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

Der CharCell a Fall entspricht, wenn der Konstruktor CharCell verwendet worden ist und a wird der Wert als CharCell verwendet werden ‚s-Parameter (und damit hat Typen Char wie das ist, CharCell‘ s Parametertyp).

Verwandte Themen