2015-10-29 22 views
6

Patrząc na Haskell Servant package istnieje początkowa przykład definiowania usługa API jak:Zrozumienie Haskell Typ Poziom Literówki

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

mam problemy ze zrozumieniem, co to oznacza i będę wdzięczny za wyjaśnienie, co następuje:

  1. :> i :<|> są konstruktorzy Infix. Czy deklaracja tego typu oznacza, że ​​są one zdefiniowane tutaj lub są tutaj używane? A może zdefiniowano tutaj :>, ale :<|> jest zdefiniowany gdzie indziej? Albo coś innego? Nie wiem, jak czytać ten typ.

  2. Co to jest '[JSON]? Czy jest to rodzaj literalnej listy poziomu? Co robi cytat?

Odpowiedz

5

The (Infix) konstruktorzy stosowane tutaj, i muszą one być zdefiniowane gdzie indziej w data lub newtype zgłoszeń. type deklaracje nie produkują żadnych konstruktorów.

'[JSON] to rzeczywiście lista poziomów typu, odpowiadająca JSON ': '[]. Pojedynczy cytat wskazuje, że konstruktor danych jest podnoszony do konstruktora typów. Nie jestem pewien, jakie ma głębokie znaczenie, ale przynajmniej unika zamieszania, które mogłoby w innym przypadku wynikać z faktu, że konstruktorzy danych i konstruktorzy typów mogą wymieniać się nazwami.

+0

Dzięki. Dokumentacja GHC na literałach poziomu nie mówi nic o listach. Czy wiesz, gdzie to jest zdefiniowane? – Ana

+2

@Ana poziomowe wersje wszystkich promowanych typów danych są automatycznie definiowane, gdy używane jest rozszerzenie 'DataKinds'. [Zobacz tutaj, aby poznać szczegóły.] (Https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/promotion.html) –

2

Tylko dla przypomnienia, oto rzeczywiste definicje :<|> i :>.

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

Ten ostatni nie ma żadnego konstruktora, ponieważ nie musimy go podczas łączenia ze sobą zajmujące się wnioskami, natomiast jesteśmy ponownym użyciem :<|> symbol kiedy skleić kilka osób zajmujących się wnioskami razem, na poziomie wartości, w przeciwieństwie do zestawiania opisów dla kilku punktów końcowych na poziomie typu, gdzie używamy również operatora :<|>. W drugim przypadku odwołujemy się jednak do konstruktora typu :<|>, natomiast gdy używamy go na procedurach obsługi, odwołujemy się do konstruktora danych.