Как перейти на серверный тип обслуживания?

#haskell #servant

Вопрос:

У меня возникли проблемы со следующим кодом:

 {-# LANGUAGE DataKinds #-}
{-# LANGUAGE TypeOperators #-}

module API where

import           Data.Text
import           Servant.API
import           Servant
import           Repository 
import           FileOperation
import           Util
import           Config
import qualified Data.Map                   as M
import           Control.Monad.State.Strict (liftIO)
import           Network.Wai.Handler.Warp

type RepositoryAPI = "repository" :> "all" :> Get '[JSON] [Repository] 
                :<|> "all" :> "repository" :> Get '[JSON] [Repository]

server :: Server RepositoryAPI
server = do
  repositoriesMap <- liftIO $ loadFromFile repositoryMapFile
  let repositories = M.elems repositoriesMap in do
    return repositories 

repositoryAPI :: Proxy RepositoryAPI 
repositoryAPI = Proxy

app :: Application
app = serve repositoryAPI server

main :: IO ()
main = run 8081 app
 

Ошибка, которую я получаю, такова:

 API.hs:22:3: error:
    • Couldn't match type ‘[a0]’ with ‘Handler [Repository]’
      Expected type: Server RepositoryAPI
        Actual type: Handler [Repository] :<|> [a0]
    • In a stmt of a 'do' block:
        repositoriesMap <- liftIO $ loadFromFile repositoryMapFile
      In the expression:
        do repositoriesMap <- liftIO $ loadFromFile repositoryMapFile
           let repositories = ... in do return repositories
      In an equation for ‘server’:
          server
            = do repositoriesMap <- liftIO $ loadFromFile repositoryMapFile
                 let ... in do ...
   |
22 |   repositoriesMap <- liftIO $ loadFromFile repositoryMapFile
   |   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 

Вопрос в том, как правильно поднять, чтобы лифт возвращал тип сервера-слуги?

Ответ №1:

Проблема не имеет ничего общего с подъемом. Реальная проблема заключается в том , что вы указали только один Handler , но вашему серверу нужны два Handler s, один для "repository" :> "all" :> Get '[JSON] [Repository] и один для "all" :> "repository" :> Get '[JSON] [Repository] . Вот скелет для вашего второго (замените существующий server на этот):

 getRepositoryAll :: Handler [Repository]
getRepositoryAll = do
  repositoriesMap <- liftIO $ loadFromFile repositoryMapFile
  let repositories = M.elems repositoriesMap in do
    return repositories 

getAllRepository :: Handler [Repository]
getAllRepository = undefined -- fill this in

server :: Server RepositoryAPI
server = getRepositoryAll :<|> getAllRepository