Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/svg/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Haskell 如何在YesSOD中以类似的方式组合函数?_Haskell_Yesod - Fatal编程技术网

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…