I am going through the servant tutorial found here. There is a partial implementation that is left for the user to figure out what it should be.
type APIFor a i =
Get '[JSON] [a]
:<|> ReqBody '[JSON] a :> PostNoContent
:<|> Capture "id" i :>
( Get '[JSON] a
:<|> ReqBody '[JSON] a :> PutNoContent
:<|> DeleteNoContent
)
serverFor :: Handler [a]
-> (a -> Handler NoContent)
-> (i -> Handler a)
-> (i -> a -> Handler NoContent)
-> (i -> Handler NoContent)
-> Server (APIFor a i)
serverFor = error "..." -- What should be here?
Following from the previous examples I came up with the implementation:
serverFor = listing :<|> ops
where
listing :: Handler [a]
listing = error ""
ops a i =
creating a
:<|> getById i
:<|> updating i a
:<|> deleting i
where
creating :: a -> Handler NoContent
creating a = error ""
getById :: i -> Handler a
getById id = error ""
updating :: i -> a -> Handler NoContent
updating i a = error ""
deleting :: i -> Handler NoContent
deleting i = error ""
But am getting the error:
• Couldn't match expected type ‘Handler [a]
-> (a -> Handler NoContent)
-> (i -> Handler a)
-> (i -> a -> Handler NoContent)
-> (i -> Handler NoContent)
-> Server (APIFor a i)’
with actual type ‘Handler [a0]
:<|> (a1
-> i0
-> Handler NoContent
:<|> (Handler a2
:<|> (Handler NoContent :<|> Handler NoContent)))’
• Possible cause: ‘(:<|>)’ is applied to too many arguments
In the expression: listing :<|> ops
I understand what the error is saying but do not know how to implement it correctly. Is anyone able to help with what the correct implementation should be?
The signature of the serverFor
function says it takes handler functions and builds the Server
.
serverFor list create get update delete =
-- combine handlers according to API type
list :<|> create :<|> (\i -> get i :<|> update i :<|> delete i)
you can then call serverFor
for your specific types.
data User = User {id :: Int}
server :: Server (APIFor User Int)
server = serverFor listing creating getById updating deleting
where
listing :: Handler [User]
listing = error ""
creating :: User -> Handler NoContent
creating a = error ""
getById :: Int -> Handler User
getById id = error ""
updating :: Int -> User -> Handler NoContent
updating i a = error ""
deleting :: Int -> Handler NoContent
deleting i = error ""