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?
CodePudding user response:
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 ""
CodePudding user response:
• Couldn't match type ‘()’
with ‘Scripts.DatumType a0
-> Scripts.RedeemerType a0 -> ScriptContext -> Bool’
Expected type: template-haskell-2.16.0.0:Language.Haskell.TH.Syntax.Q
(template-haskell-2.16.0.0:Language.Haskell.TH.Syntax.TExp
(PlutusTx.CompiledCode
(Scripts.ValidatorType a0 -> Scripts.WrappedValidatorType)))
Actual type: template-haskell-2.16.0.0:Language.Haskell.TH.Syntax.Q
(template-haskell-2.16.0.0:Language.Haskell.TH.Syntax.TExp
(PlutusTx.CompiledCode
(() -> MyRedeemer -> ScriptContext -> Bool)))
• In the expression: PlutusTx.compile [|| mkValidator ||]
In the Template Haskell splice
$$(PlutusTx.compile [|| mkValidator ||])
In the second argument of ‘Scripts.mkTypedValidator’, namely
‘$$(PlutusTx.compile [|| mkValidator ||])’
|
56 | $$(PlutusTx.compile [|| mkValidator ||])
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^