Haskell Spock IO在获取路由ActionCtxt错误中



我尝试在Web应用程序的路由定义(Spock Weberver)中返回一个UUID。

路线非常简单

get("PATH") $ do
 text "Hello World"

现在,我尝试通过data.uuid.v1模块通过nextRandom返回UUID。该功能返回IO(Maybe UUID)值。

所以我想,因为我在IO中并与另一个IO一起工作,所以我必须简单地用<-绑定值,例如:

get ("id") $ do
    uuid<-nextUUID
    json . pack $ show $ uuid

但编译器说不:

Couldn't match type ‘ActionCtxT ctx0 m0’ with ‘IO’
      Expected type: IO b0
        Actual type: ActionCtxT ctx0 m0 b0
    • In a stmt of a 'do' block: json . pack $ show $ uuid
      In the second argument of ‘($)’, namely
        ‘do { uuid <- nextUUID;
              json . pack $ show $ uuid }’

为什么要丢弃这个错误?我可以轻松地使用一个简单的打印示例来创建UUID,但是在Spock中,我不明白Actionctxt的作用以及为什么无法在其中进行UUID io。

所以我想,因为我在IO并与另一个IO

一起工作

这是这里的麻烦,当您在Spock中布线时,您不在IO中。错误消息告诉您您真正在哪个上下文:ActionCtxT ctx0 m0。根据文档,这是一个单调的变压器堆栈,捆绑了效果和状态。

您可以使用liftIO将IO计算"抬高"到正确的类型中。

get ("id") $ do
    uuid <- liftIO nextUUID
    json . pack $ show $ uuid

基于libbys有用的答案,我刚刚添加了Maybe UUIDNothing的捕获量。这里完整的程序:

{-# LANGUAGE OverloadedStrings #-}

module Main where
import Web.Spock hiding (head)
import Web.Spock.Config
import Data.UUID.V1
import Data.Pool
import Control.Monad.IO.Class
import Database.PostgreSQL.Simple
import Data.Aeson (Value(Null))
import qualified Network.HTTP.Types.Status as Http
type AppAction a = SpockActionCtx () Connection AppSession AppState a
data AppState = EmptyState
data AppSession = EmptySession

main :: IO ()
main =
  do pool<-createPool (connect (ConnectInfo "localhost" 5432 "" "" "envelopes") ) close 1 10 10
     spockCfg <- defaultSpockCfg EmptySession (PCPool pool) EmptyState
     runSpock 8080 (spock spockCfg app)
app :: SpockM Connection AppSession AppState ()
app = do 
    get ("json/id") $ do
      uuid<-liftIO nextUUID
      case uuid of
        Nothing -> do 
          setStatus Http.status500
          json Null
        Just x  -> json $ show x

相关内容

  • 没有找到相关文章

最新更新