2015-10-29 6 views
6

am Haskell Servant package Sehen, gibt es ein erstes Beispiel einen Webservice-API als definieren:Verständnis Haskell Typ Stufe Literale

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

Ich habe Probleme zu verstehen, was das bedeutet und wäre eine Erklärung für den folgenden schätzen:

  1. :> und :<|> sind Infix Bauer. Bedeutet diese Typdeklaration, dass sie hier definiert sind oder hier verwendet werden? Oder vielleicht :> ist hier definiert, aber :<|> ist anderswo definiert? Oder etwas anderes? Nicht sicher, wie man diesen Typ liest.

  2. Was ist '[JSON]? Ist das eine literale Liste auf Typenebene? Was macht das Zitat?

Antwort

5

Die (Infix) Konstrukteure hier verwendet werden, und sie müssen an anderer Stelle in data oder newtype Erklärungen definiert werden. type Deklarationen erzeugen keine Konstrukteure jeglicher Art.

'[JSON] ist in der Tat eine Typenliste, die JSON ': '[] entspricht. Das einfache Anführungszeichen gibt an, dass ein Datenkonstruktor an einen Typkonstruktor übergeben wird. Ich bin mir nicht sicher, welche tiefe Bedeutung das hat, aber zumindest vermeidet es Verwirrung, die sonst aus der Tatsache entstehen könnte, dass Datenkonstruktoren und Typkonstruktoren Namen teilen können.

+0

Danke. Die GHC-Dokumentation zu Literalen auf Typenebene sagt nichts über Listen aus. Weißt du, wo dies definiert ist? – Ana

+2

@Ana-Versionen aller aktivierbaren Datentypen werden automatisch definiert, wenn die Erweiterung 'DataKinds' verwendet wird. [Siehe hier für Details.] (Https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/promotion.html) –

2

Nur zur Erinnerung, hier sind die tatsächlichen Definitionen von :<|> und :>.

-- 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 

Letztere hat keinen Konstruktor, weil wir es nicht brauchen, wenn sie zusammen Request-Handler kombiniert, während wir das :<|> Symbol sind wiederverwenden, wenn wir mehrere Request-Handler zusammenkleben, auf dem Wert-Ebene, im Gegensatz zum Zusammenstellen von Beschreibungen für mehrere Endpunkte auf Typ-Ebene, wo wir auch den Operator :<|> verwenden. In letzterem Fall verweisen wir jedoch auf :<|> -the-type-constructor, während wir, wenn wir es auf Handlern verwenden, auf :<|> -the-data-constructor verweisen.