我正在寻找关于编写惯用PureScript代码的反馈信息。下面的代码是从Twitter中读取的示例代码。助手方法的签名如下:
-- read consumer credentials from a config file
readConfig :: String -> Aff (Either String TwitterCredentials)
-- get the bearer authentication using the consumer credentials
getTokenCredentials :: TwitterCredentials -> Aff (Either String BearerAuthorization)
-- read the Twitter API using the bearer authentication
showResults :: BearerAuthorization -> String -> Aff (Either String SearchResults)我的代码是:
main :: Effect Unit
main = launchAff_ do
let searchTerm = "PureScript"
config <- readConfig "./config/twitter_credentials.json"
case config of
Left errorStr -> errorShow errorStr
Right credentials -> do
tokenCredentialsE <- getTokenCredentials credentials
case tokenCredentialsE of
Left error ->
errorShow error
Right tokenCredentials -> do
resultsE <- showResults tokenCredentials searchTerm
case resultsE of
Left error ->
errorShow error
Right result ->
liftEffect $ logShow $ "Response:" <> (show result.statuses)如您所见,有许多嵌套的Either语句,我三次调用errorShow。如何编写这段代码,使其更具可读性,并可能删除代码重复?
发布于 2018-10-29 03:09:42
您可以将助手函数从返回Aff (Either String a)转换为ExceptT String Aff a。ExceptT是一个单变量转换器,它使用Either e a代替值,这意味着编译后的代码看起来大致相同。但是在源级,您可以忽略这些错误直到结束,从而获得可读性并减少重复。
如果您控制帮助函数的源,只需直接重写它们:使用Left代替返回throwError,而不是返回Right,而是使用pure。
另一方面,如果您不控制帮助程序的源代码,则可以使用另一个小助手函数来转换它们:
eitherToExcept :: forall e a. Aff (Either e a) -> ExceptT e Aff a
eitherToExcept action = either throwError pure <$> lift action现在,您的main函数可以在ExceptT monad中完成所有工作,让它在幕后传播错误,并且只在最后使用runExceptT将结果转换回Either。
main = launchAff_ $ either errorShow (liftEffect <<< logShow) $ runExceptT do
let searchTerm = "PureScript"
credentials <- eitherToExcept $ readConfig "./config/twitter_credentials.json"
tokenCredentials <- eitherToExcept $ getTokenCredentials credentials
results <- eitherToExcept $ showResults tokenCredentials searchTerm
pure $ "Response:" <> (show results.statuses)因为我没有时间编译和验证代码,所以这里和那里可能会有一些排印。
https://stackoverflow.com/questions/53037222
复制相似问题