haskell - Does the expressiveness of monads come at the expense of code reuse? -
when compare binary operations of applicative , monad type class
(<*>) :: applicative f => f (a -> b) -> f -> f b (=<<) :: monad m => (a -> m b) -> m -> m b two differences become apparent:
apexpects normal, pure function, whereasbindexpects monadic action, must return monad of same type- with
apsequence of actions determined applicative, whereasbindmonadic action can determine control flow
so monads give me additional expressive power. however, since no longer accept normal, pure functions, expressiveness seems come @ expense of code reuse.
my conclusion might naive or false, since have merely little experience haskell , monadic computations. light in dark appreciated!
code reuse advantage if can reuse code want.
ghci> putstrln =<< getline sulfur sulfur ghci> here, (=<<) picks string result produced in io context getline , feeds putstrln, prints said result.
ghci> :t getline getline :: io string ghci> :t putstrln putstrln :: string -> io () ghci> :t putstrln =<< getline putstrln =<< getline :: io () now, in type of fmap/(<$>)...
ghci> :t (<$>) (<$>) :: functor f => (a -> b) -> f -> f b ... possible b io (), , therefore nothing stops using putstrln it. however...
ghci> putstrln <$> getline sulfur ghci> ... nothing printed.
ghci> :t putstrln <$> getline putstrln <$> getline :: io (io ()) executing io (io ()) action won't execute inner io () action. that, need additional power of monad, either replacing (<$>) (=<<) or, equivalently, using join on io (io ()) value:
ghci> :t join join :: monad m => m (m a) -> m ghci> join (putstrln <$> getline) sulfur sulfur ghci> like chi, have trouble understanding premises of question. seem expect 1 of functor, applicative , monad turn out better others. not case. can more things applicative functor, , more monad. if need additional power, use suitably powerful class. if not, using less powerful class lead simpler, clearer code , broader range of available instances.
Comments
Post a Comment