Last active
February 11, 2018 13:05
-
-
Save ifesdjeen/4be994aea5846aa1c2fe to your computer and use it in GitHub Desktop.
I've got that piece of code that looks extremely overcomplicated to me. Even though every operation by itself is simple, the "sum" of operations is simply insane.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
data Query = Query | |
data SomeObj = SomeObj | |
data IoOnlyObj = IoOnlyObj | |
data Err = Err | |
-- There's a decoder function that makes some object from String | |
decodeFn :: String -> Either Err SomeObj | |
decodeFn = undefined | |
-- There's a query, that runs against DB and returns array of strings | |
fetchFn :: Query -> IO [String] | |
fetchFn = undefined | |
-- there's some additional "context initializer", that also has IO | |
-- side-effects | |
makeIoOnlyObj :: [SomeObj] -> IO [(SomeObj, IoOnlyObj)] | |
makeIoOnlyObj = undefined | |
-- and now, there's a pipeline function, that takes query, | |
-- decodes results, and then runs another IO operation with the | |
-- results of query. And it seems to me that there are much much | |
-- better ways of implementing such things. | |
-- | |
-- `makeIoOnlyObj` returns IO-wrapped result, and we need | |
-- return IO Either-wrapped. | |
-- | |
-- So far what I've got is as follows. How do I improve it? | |
pipelineFn :: Query | |
-> IO (Either Err [(SomeObj, IoOnlyObj)]) | |
pipelineFn query = do | |
a <- fetchFn query | |
case sequence (map decodeFn a) of | |
(Left err) -> return $ Left $ err | |
(Right res) -> do | |
a <- makeIoOnlyObj res | |
return $ Right a |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Another variation of
traverse
version, suggested by @bitemyapp is: