Generalisation of question (read below for specifics to my current problem)
Given a function type definition: f :: MonadIO m -> a -> m B
where B
is a custom datatype B = B {x y z ...}
how can I access a member such as x
from the value returned by f
?
Problem
I am trying to use the wave package to make an application, but I have a simple problem: I wish to access waveFileFormat
of the data type Wave
However simply doing waveFileFormat $ readWaveFile "file"
does not work because readWaveFile "file"
is actually a MonadIO m => m Wave
returned by readWaveFile.
What I have tried and does not work
readWaveFile "file" >>= waveFileFormat
readWaveFile "file" >> waveFileFormat
What works (but looks inelegant and horribly long for what it is)
do{wave<-readWaveFile "file"; return $ waveFileFormat wave}
This approach however will not work outside a `do` block because of the assignment . It is also extremely long and like boilerplate. How can I avoid this?
CodePudding user response:
You can use fmap
(or its infix operator form, (<$>)
):
waveFileFormat <$> readWaveFile "file"
This has type MonadIO m => m WaveFormat
. You can't ever escape the monad, but you can keep manipulating its value to your heart's content.