如何在Yesod中组合函数?

时间:2017-05-29 15:32:00

标签: haskell yesod

我有一个Either

的包装器
newtype Answer a = Answer (Either Text a)

可以转换为JSON:

instance ToJSON a => ToJSON (Answer a) where
toJSON (Answer (Left msg)) = object
  [ "error"   .= True
  , "message" .= msg
  , "data"    .= Null
  ]
toJSON (Answer (Right val)) = object
  [ "error"   .= False
  , "message" .= pack "OK"
  , "data"    .= val
  ]

答案有两种:

errorAnswer :: Text -> Answer a
errorAnswer = Answer . Left

valueAnswer :: a -> Answer a
valueAnswer = Answer . Right

我在Handler monad中运行了一组函数并返回Answer

有些功能测试了一些东西:

checkSomething :: Handler (Answer a) -> Handler (Answer a)
checkSomething action = do
  if sometingIsWrong
    then pure (errorAnswer "Something was wrong")
    else action

其他功能操纵TVar中的App变量:

readSomething
  :: (App -> TVar a) -> (a -> Either Text b) -> Handler (Answer a)
readSomething var f =
  readVar var >>= pure . Answer . f
  where
    readVar var = getYesod >>= liftIO . readTVarIO . var

上面这两个函数很容易构成:

handleRequest :: ToJSON a => Handler (Answer a)
handleRequest =
  checkSomething $ readSomething someVar someProjection

但是当我有更多支票checkSomething时,它会变得很难。另外,我想将returnJson放在某处,最后返回Value

有没有办法在Either样式中编写处理程序(同样,Maybe喜欢)?例如:

handleRequest :: Handler (Answer Int)
handleRequest = do
  checkSomething0 -- Do not continue if (Answer (Left _))
  checkSomething1 -- Do not continue if (Answer (Left _))
  doSomething     -- Everything above was fine

一个想法是将Alternative实例添加到Handler (Answer a),但这是一个问题:

empty = Answer (Left ???)

我在这里丢失了一条消息,如果发生错误,服务器应该返回。

0 个答案:

没有答案