I often find myself wanting to insert regular functions into a "binded" sequence. Like in this contrived example:
getLine >>= lift (map toUpper) >>= putStrLn
I need to define the lift function lift :: (a -> b) -> a -> m b
to make this work. Problem is I don't know of such a function, and Hoogle doesn't seem to either. I find this odd since this makes totally sense to me.
Now, there are probably other ways to make this work, but I like the way point-free style code allows me to scan the line in one pass to figure out what is happening.
let lift f x = return (f x) in
getLine >>= lift (map toUpper) >>= putStrLn
My question boils down to this: am I missing something or how come there isn't a function like lift. My experience in Haskell is still very limited, so I am assuming that most people solve this in a different way. Can someone explain to me the idiomatic way of solving this.
A pure function does not have side-effects and its result does not depend on anything other than its inputs. A pure function guarantees that for a given input it will produce the same output no matter how many times it is called.
A function must pass two tests to be considered “pure”: Same inputs always return same outputs. No side-effects.
Pure functions return the same output if we use the same input parameters. However, impure functions give different outcomes when we pass the same arguments multiple times. Pure functions always return some results. Impure functions can execute without producing anything.
There are three idiomatic ways.
Don't use bind; use the first hit on your Hoogle search instead:
liftM (map toUpper) getLine >>= putStrLn
There are a variety of alternative spellings of liftM
, such as fmap
or (<$>)
.
Inline the lift
function you defined:
getLine >>= return . map toUpper >>= putStrLn
Use the monad laws to fuse the last two binds in option 2:
getLine >>= putStrLn . map toUpper
Use the Functor
instance in such cases:
> import Data.Char
> import Data.Functor
> map toUpper <$> getLine >>= putStrLn
foo
FOO
>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With