[Haskell-cafe] best practice for lifting of IO and could lifting

Dimitri DeFigueiredo defigueiredo at ucdavis.edu
Mon Oct 26 16:36:40 UTC 2015

It seems I need to read Oleg's paper. I might have over simplified the 
problem by using ReaderT in my example. In my original problem this role 
is played by the Pipes library (and instead of using 'ask', I wanted to 
'yield' control to a downstream pipe).

Thanks for the feedback!


On 10/26/15 7:55 AM, Oleg wrote:
> Roman Cheplyaka wrote:
>> Not really. You are passing 'ref' into myReadFile by hand here. If you
>> are willing to pass parameters by hand, there is no need in IORef at
>> all; you could just as well pass header directly.
> I confess in embellishing the problem and tacitly upgrading Reader to
> the State. The original problem seemed too simple. In penance, I show
> the solution to the original problem, using exactly the signature of
> the original poster, and using exactly his code for myReadFile,
> (but with the lifted type, which is what he wanted, it seems).
>> data ColumnHeaders = FirstLine | None
>> getFileContents :: ReaderT ColumnHeaders IO String
>> getFileContents = do
>>    header <- ask -- can ask it here
>>    lift $ withCSV "data.csv" (\handle -> runReaderT (myReadFile handle) header)
>>       where
>> myReadFile :: Handle -> ReaderT ColumnHeaders IO String
>> myReadFile handle = do
>>    header <- ask   -- Now, we can ask it, alright
>>    case header of
>>      None      -> return ""
>>      FirstLine -> lift $ hGetLine handle -- skip first line
>>    text <- lift $ hGetContents handle
>>    return text
> The idea is simple: since withCSV wants its callback to be IO rather
> than ReaderT IO, it means the withCSV is not capable of altering the
> environment of the callback. Therefore, the myReadFile is executed in
> the same environment, regardless of the Handle. Once we understand
> this, the solution is trivial.
> So, to answer the question of the original poster: it seems we can do
> what he wants withCSV he got. There is no need to ask withCSV author
> for anything.
>> I agree that *given a ReaderT* (or implicit params, or your implicit
>> configurations), you can emulate StateT/WriterT using IORefs (but only
>> one way of stacking w.r.t. exceptions).
> Actually, it is easy to get other ways of `stacking with respect to
> exceptions.' Once we get persistent state (which is what IORef
> provide), we can always discard that state by writing an appropriate
> exception handler. I guess I can make another stab at monad
> transformers and say that thinking in terms of stacks is not always
> productive.

More information about the Haskell-Cafe mailing list