@@ -0,0 +1,63 @@
1+{-# LANGUAGE DataKinds #-}
2+{-# LANGUAGE TypeFamilies #-}
3+{-# LANGUAGE DeriveGeneric #-}
4+{-# LANGUAGE TypeOperators #-}
5+{-# LANGUAGE FlexibleInstances #-}
6+{-# LANGUAGE OverloadedStrings #-}
7+module GS4 where
8+
9+import Data.Aeson
10+import Data.Foldable (foldMap)
11+import GHC.Generics
12+import Lucid
13+import Network.Wai
14+import Servant
15+import Servant.HTML.Lucid
16+
17+data Person = Person
18+ { firstName :: String
19+ , lastName :: String
20+ , age :: Int
21+ } deriving Generic -- for the JSON instance
22+
23+-- JSON serialization
24+instance ToJSON Person
25+
26+-- HTML serialization of a single person
27+instance ToHtml Person where
28+ toHtml p =
29+ tr_ $ do
30+ td_ (toHtml $ firstName p)
31+ td_ (toHtml $ lastName p)
32+ td_ (toHtml . show $ age p)
33+
34+ toHtmlRaw = toHtml
35+
36+-- HTML serialization of a list of persons
37+instance ToHtml [Person] where
38+ toHtml persons = table_ $ do
39+ tr_ $ do
40+ td_ "first name"
41+ td_ "last name"
42+ td_ "age"
43+
44+ foldMap toHtml persons
45+
46+ toHtmlRaw = toHtml
47+
48+persons :: [Person]
49+persons =
50+ [ Person "Isaac" "Newton" 372
51+ , Person "Albert" "Einstein" 136
52+ ]
53+
54+type PersonAPI = "persons" :> Get '[JSON, HTML] [Person]
55+
56+personAPI :: Proxy PersonAPI
57+personAPI = Proxy
58+
59+server :: Server PersonAPI
60+server = return persons
61+
62+app :: Application
63+app = serve personAPI server