2017-02-25 21 views
0

Webアプリケーション(Spockウェブサーバー)のルート定義内でuuidを返そうとしています。GETルート内のHaskell Spock IO ActionCtxTエラー

ルートは今、私はData.UUID.V1モジュールからnextRandomを経由してUUIDを返すようにしようと

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

を定義するために非常に単純です。 この関数は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を実行できない理由を理解できません。

答えて

2

だから、私はIOに居ないので、考えて、ここではトラブルだ別のIO

で動作しますが、スポックにルーティングしているとき、あなたはIOではありません。エラーメッセージは、あなたが本当にどのコンテキストにいるかを示します:ActionCtxT ctx0 m0the docsによれば、それはmonad transformer stackで、エフェクトと状態がバンドルされています。

liftIOを使用して、IO計算を正しいタイプに「持ち上げる」ことができます。 Libbys役立つ回答に基づいて

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

それはそれをしました。リフトIO、モナドトランススタック?まあ、まあ、私は結局そこに着くでしょう。 uuidは[おそらくUUID]なので、ショーは 'Just 03fcbcbe-fbf0-11e6-8001-a8667f260e4c'を返しています。私は何とかそれからアクチュアールの価値を得る方法を見つけ出し、ここで完全な正しい結果を投稿すると思います。感謝万円。 –

0

私はちょうどMaybe UUIDNothingのためのキャッチを追加しました。ここに完全なprogramm:

{-# 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 
関連する問題