<commit_before>homepage: ''
changelog-type: ''
hash: 7f38e8d6729ec6640b3734c3ad161411ae179cef6be92cb6f7eaa02d8b958103
test-bench-deps:
  warp: -any
  base: ! '>=4.7 && <4.10'
  servant-generic: -any
  text: -any
  servant-server: ! '>=0.7.1'
  servant: ! '>=0.7.1'
maintainer: <EMAIL>
synopsis: Specify Servant APIs with records.
changelog: ''
basic-deps:
  base: ! '>=4.7 && <4.10'
  servant-server: ! '>=0.7.1'
  servant: ! '>=0.7.1'
all-versions:
- '0.1.0.0'
author: <NAME>
latest: '0.1.0.0'
description-type: markdown
description: ! "[![Build Status](https://travis-ci.org/chpatrick/servant-generic.svg?branch=master)](https://travis-ci.org/chpatrick/servant-generic)
  [![Hackage](https://img.shields.io/hackage/v/servant-generic.svg)](http://hackage.haskell.org/package/servant-generic)\n\ntl;dr\n-----\nSpecify
  Servant APIs with simple records instead of `:<|>` trees.\n\n```haskell\ndata Site
  route = Site\n  { about :: route :-\n      \"about\" :> Get '[PlainText] Text\n
  \ , faq :: route :-\n      \"faq\" :> Get '[PlainText] Text\n  } deriving Generic\n\nsiteServer
  :: Site AsServer\nsiteServer = Site\n  { about = return \"about\"\n  , faq = return
  \"faq\"\n  }\n\ntype Api = ToServant (Site AsApi)\n\nmain :: IO ()\nmain = run 31337
  $ serve (Proxy :: Proxy Api) (toServant siteServer)\n```\n\nSo long and thanks for
  all the `:<|>`\n-------------------------------------\nServant is great for building
  typesafe APIs. However, its biggest weakness is that you need to specify APIs as
  a tree of `:<|>` operators:\n\n```haskell\ntype SiteOld =\n       \"about\" :> Get
  '[PlainText] Text\n  :<|> \"faq\" :> Get '[PlainText] Text\n  :<|> \"subsite\" :>
  SubSiteOld\n\ntype SubSiteOld =\n       \"echo\" :> Capture \"x\" Text :> Get '[PlainText]
  Text\n  :<|> \"timestwo\" :> Capture \"x\" Int :> Get '[PlainText] Text\n\nsiteOldServer
  :: Server SiteOld\nsiteOldServer =\n       return \"about\"\n  :<|> subSiteOldServer\n
  \ :<|> return \"faq\"\n\nsubSiteOldServer :: Server SubSiteOld\nsubSiteOldServer
  =\n       return\n  :<|> (\\x -> return $ T.pack $ show (x * 2))\n```\n\nThis is
  cumbersome because you need to remember the exact order of routes when you are implementing
  the API. Not only that, but if you get anything wrong, you are treated with an incomprehensible
  error message. Let's see what happens if we mix up the implementations of `/faq`
  and `/subsite`:\n\n```\n    • Couldn't match type ‘(Text\n                            ->
  transformers-0.5.2.0:Control.Monad.Trans.Except.ExceptT\n                                 ServantErr<commit_msg>Update from Hackage at 2017-12-06T10:15:07Z<commit_after>homepage: ''
changelog-type: ''
hash: 2c753f86240a3a2b2c0dbc561e4e56b16503c6c939b19e902c53adcad1d5d6a5
test-bench-deps:
  warp: -any
  base: ! '>=4.7 && <4.11'
  servant-generic: -any
  text: -any
  servant-server: ! '>=0.7.1'
  servant: ! '>=0.7.1'
  network-uri: -any
maintainer: <EMAIL>
synopsis: Specify Servant APIs with records.
changelog: ''
basic-deps:
  base: ! '>=4.7 && <4.11'
  servant-server: ! '>=0.7.1'
  servant: ! '>=0.7.1'
all-versions:
- '0.1.0.0'
- '0.1.0.1'
author: <NAME>
latest: '0.1.0.1'
description-type: markdown
description: ! "[![Build Status](https://travis-ci.org/chpatrick/servant-generic.svg?branch=master)](https://travis-ci.org/chpatrick/servant-generic)
  [![Hackage](https://img.shields.io/hackage/v/servant-generic.svg)](http://hackage.haskell.org/package/servant-generic)\n\ntl;dr\n-----\nSpecify
  Servant APIs with simple records instead of `:<|>` trees.\n\n```haskell\ndata Site
  route = Site\n  { about :: route :-\n      \"about\" :> Get '[PlainText] Text\n
  \ , faq :: route :-\n      \"faq\" :> Get '[PlainText] Text\n  } deriving Generic\n\nsiteServer
  :: Site AsServer\nsiteServer = Site\n  { about = return \"about\"\n  , faq = return
  \"faq\"\n  }\n\ntype Api = ToServant (Site AsApi)\n\nmain :: IO ()\nmain = run 31337
  $ serve (Proxy :: Proxy Api) (toServant siteServer)\n```\n\nSo long and thanks for
  all the `:<|>`\n-------------------------------------\nServant is great for building
  typesafe APIs. However, its biggest weakness is that you need to specify APIs as
  a tree of `:<|>` operators:\n\n```haskell\ntype SiteOld =\n       \"about\" :> Get
  '[PlainText] Text\n  :<|> \"faq\" :> Get '[PlainText] Text\n  :<|> \"subsite\" :>
  SubSiteOld\n\ntype SubSiteOld =\n       \"echo\" :> Capture \"x\" Text :> Get '[PlainText]
  Text\n  :<|> \"timestwo\" :> Capture \"x\" Int :> Get '[PlainText] Text\n\nsiteOldServer
  :: Server SiteOld\nsiteOldServer =\n       return \"about\"\n  :<|> subSiteOldServer\n
  \ :<|> return \"faq\"\n\nsubSiteOldServer :: Server SubSiteOld\nsubSiteOldServer
  =\n       return\n  :<|> (\\x -> return $ T.pack $ show (x * 2))\n```\n\nThis is
  cumbersome because you need to remember the exact order of routes when you are implementing
  the API. Not only that, but if you get anything wrong, you are treated with an incomprehensible
  error message. Let's see what happens if we mix up the implementations of `/faq`
  and `/subsite`:\n\n```\n    • Couldn't match type ‘(Text\n                            ->
  transformers-0.5.2.0:Control.Monad.Trans.Except.ExceptT\n                                 ServantErr
{'fraction_non_alphanumeric': 0.19144486692015208, 'fraction_numerical': 0.03365019011406844, 'mean_word_length': 2.9231916480238627, 'pattern_counts': {'":': 0, '<': 29, '<?xml version=': 0, '>': 59, 'https://': 6, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 7, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4310823', 'n_tokens_mistral': 2089, 'n_tokens_neox': 1965, 'n_words': 464}