1

我是 Haskell 的新手。我想用 scotty 和持久性创建简单的 crud rest api。我在一张表中使用 sqlite todo (title text, description text),我在表中有一些记录。/todos我的意思是以json 格式显示 enpoint 上的所有记录。当我打印它时,我得到一个错误

  • Couldn't match expected type ‘Data.Text.Internal.Lazy.Text’
                  with actual type ‘[Entity ToDo]’
    • In the first argument of ‘text’, namely ‘(_ToDo)’
      In a stmt of a 'do' block: text (_ToDo)
      In the second argument of ‘($)’, namely
        ‘do _ToDo <- liftIO readToDo
            text (_ToDo)’
   |
69 |     text(_ToDo)
   |          ^^^^^

我的代码:

{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE EmptyDataDecls       #-}
{-# LANGUAGE FlexibleContexts     #-}
{-# LANGUAGE FlexibleInstances    #-}
{-# LANGUAGE GADTs                #-}
{-# LANGUAGE OverloadedStrings    #-}
{-# LANGUAGE QuasiQuotes          #-}
{-# LANGUAGE TemplateHaskell      #-}
{-# LANGUAGE TypeFamilies         #-}
{-# LANGUAGE TypeSynonymInstances #-}
{-# OPTIONS_GHC -fno-warn-orphans #-}
{-# LANGUAGE MultiParamTypeClasses #-}
module Main where
import Data.Monoid ((<>))
import Web.Scotty
import qualified Web.Scotty as S
import Database.Persist
import Database.Persist.Sqlite
import Database.Persist.TH 
import Data.Text (Text)
import Data.Time (UTCTime, getCurrentTime)
import qualified Data.Text as T
import Control.Monad.IO.Class (liftIO)
import Control.Monad.Trans.Resource (runResourceT, ResourceT)
import Database.Persist.Sql
import Control.Monad (forM_)
import Control.Applicative
import Control.Monad.Logger
import Data.Aeson 
import Data.Default.Class
import GHC.Generics
import Control.Monad.IO.Class (liftIO)

share [mkPersist sqlSettings, mkMigrate "migrateAll"] [persistLowerCase|
ToDo
  title String
  description String
  deriving Show
|]


runDb :: SqlPersist (ResourceT (NoLoggingT IO)) a -> IO a
runDb = runNoLoggingT
    . runResourceT
    . withSqliteConn "todo.db"
    . runSqlConn


instance ToJSON ToDo where
  toJSON(ToDo title description) = object ["title" .= title, "description" .= description]



readToDo :: IO [Entity ToDo]
readToDo = (runDb $ selectList [] [LimitTo 10] )

routes :: ScottyM()
routes = do
  S.get "/hello" $ do
    text "hello world!"
  S.get "/hello/:name" $ do
    name <- param "name"
    text ("hello" <> name <> "!")
  S.get "/todos" $ do
    _ToDo <- liftIO readToDo
    text(_ToDo)

main = do
  putStrLn "Starting server...."
  scotty 7777 routes

如何纠正这个?

4

1 回答 1

0

看起来编译器指责您在 Entity ToDo-s 和 Data.Text.Lazy 列表之间进行了错误的转换。

请尝试使用pack函数手动转换:

import Data.Text.Lazy (pack)
...
routes = do
  S.get "/hello" $ do
    text "hello world!"
  S.get "/hello/:name" $ do
    name <- param "name"
    text ("hello" <> name <> "!")
  S.get "/todos" $ do
    _ToDo <- liftIO readToDo
    text(pack . show $ _ToDo)   -- explicit conversion
...
于 2018-06-27T21:15:24.303 回答