2017-09-16 5 views
3

Je n'arrive pas à comprendre pourquoi le code ci-dessous ne fonctionne pas. Je m'attendrais que puisque le type de données Command soit un ServerCommand ou un ClientCommand que n'importe quel constructeur de type qui attend un Command puisse accepter l'un ou l'autre. Je semble avoir une incompréhension fondamentale de la façon dont ces types de données devraient s'aligner.confusion de type Haskell; Impossible de faire correspondre le type attendu malgré la relation/

data ClientCommand = SEND | 
         DISCONNECT | 
         CONNECT 

data ServerCommand = CONNECTED | 
         MESSAGE | 
         RECEIPT | 
         ERROR 

data Command  = ServerCommand | ClientCommand 

type Frame   = (Command, Maybe String) 

makeConnect :: Frame 
makeConnect = (CONNECT, (Just "hello!")) 

Lorsque je tente de charger ce code dans ghci, je reçois l'erreur suivante:

GHCi, version 7.10.3: http://www.haskell.org/ghc/ :? for help 
[1 of 1] Compiling Main    (Frames.hs, interpreted) 

Frames.hs:15:16: 

    Couldn't match expected type ‘Command’ 
       with actual type ‘ClientCommand’ 
    In the expression: CONNECT 
    In the expression: (CONNECT, (Just "hello!")) 
Failed, modules loaded: none. 

Répondre

8
data Command  = ServerCommand | ClientCommand 

Cela ne fait pas ce que vous pensez. (Astuce: comparer avec data Bool = True | False, contempler la différence.)

Si vous voulez un type de données qui peut stocker soit un ServerCommand ou un ClientCommand, vous pouvez utiliser un type de bibliothèque

type Command = Either ServerCommand ClientCommand 

ou créer votre propre

data Command = S ServerCommand | C ClientCommand 

Pendant que nous y sommes, pensez à vos données redessiner long des lignes de

data ClientCommand = SEND String | 
        DISCONNECT | 
        CONNECT 

et laisser tomber la chose Frame tout à fait.