Haskell 如何在YesSOD中以类似的方式组合函数?
我在Haskell 如何在YesSOD中以类似的方式组合函数?,haskell,yesod,Haskell,Yesod,我在上有一个包装器 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)) = ob
上有一个包装器
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
其他函数操作App
中的TVar
变量:
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
有没有一种方法可以用或者类似的样式(也可以是或者类似的样式)编写处理程序?例如:
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
一个想法是向处理程序(答案a)
添加备选实例,但这里有一个问题:
empty = Answer (Left ???)
我在这里丢失了一条消息,如果出现错误,服务器应该返回哪个消息。您可能要将处理程序(答案a)
替换为@leftaroundabout,然后在getPageR=runExceptT…
等处理程序中展开ExceptT
?您可能要替换处理程序(答案a)
with.@leftaroundaound然后在处理程序中展开ExceptT
,如getPageR=runExceptT…
?