Skip to content

Instantly share code, notes, and snippets.

@bitemyapp
Forked from ifesdjeen/Haskell Simplification 1.hs
Last active August 29, 2015 14:09
Show Gist options
  • Save bitemyapp/c4bf16da16b3bace277c to your computer and use it in GitHub Desktop.
Save bitemyapp/c4bf16da16b3bace277c to your computer and use it in GitHub Desktop.
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