2015-10-29 16 views
6

Guardando il Haskell Servant package, c'è un esempio iniziale di definire un'API webservice come:intesa Tipo Haskell Livello letterali

   -- GET /date 
type MyAPI = "date" :> Get '[JSON] Date 
      -- GET /time/:tz 
     :<|> "time" :> Capture "tz" Timezone :> Get '[JSON] Time 

Sto avendo difficoltà a capire cosa significa e apprezzerei una spiegazione per quanto segue:

  1. :> e :<|> sono costruttori infissa. Questa dichiarazione di tipo significa che sono definiti qui o sono usati qui? O forse :> è definito qui ma :<|> è definito altrove? O qualcos'altro? Non sei sicuro di come leggere questo tipo.

  2. Che cos'è '[JSON]? Questa è una sorta di elenco letterale di livello testo? Cosa fa la citazione?

risposta

5

L'(infisso) costruttori sono usati qui, e devono essere definiti altrove in data o newtype dichiarazioni. Le dichiarazioni type non producono mai costruttori di alcun tipo.

'[JSON] è effettivamente un elenco di livello di tipo, equivalente a JSON ': '[]. La virgoletta singola indica che un costruttore di dati viene sollevato a un costruttore di tipi. Non sono sicuro di quale significato profondo abbia, ma almeno evita la confusione che potrebbe altrimenti derivare dal fatto che i costruttori di dati e i costruttori di tipi possono condividere nomi.

+0

Grazie. La documentazione di GHC sui letterali a livello di testo non dice nulla sulle liste. Sai dove è definito? – Ana

+2

@Le versioni di tipo AA di tutti i tipi di dati promuovibili vengono definite automaticamente quando è in uso l'estensione 'DataKinds'. [Vedi qui per i dettagli.] (Https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/promotion.html) –

2

Solo per la cronologia, ecco le definizioni effettive di :<|> e :>.

-- that's really like a pair of an 'a' and a 'b'... 
-- that can be chained in a nice way, as opposed to nested pairs. 
data a :<|> b = a :<|> b 
data a :> b 

quest'ultimo non ha alcun costruttore, perché non abbiamo bisogno che quando si combinano gestore della richiesta insieme, mentre noi stiamo riutilizzando il simbolo :<|> quando incolliamo diversi gestori delle richieste insieme, a livello di valore, al contrario di mettere insieme le descrizioni per diversi endpoint a livello di testo, dove usiamo anche l'operatore :<|>. In quest'ultimo caso, stiamo facendo riferimento a :<|> -the-type-constructor, mentre quando lo utilizziamo su gestori, facciamo riferimento a :<|> -the-data-constructor.