Functions are Monads.

:i Monad
class Applicative m => Monad (m :: * -> *) where
  (>>=) :: m a -> (a -> m b) -> m b
  (>>) :: m a -> m b -> m b
  return :: a -> m a
...
instance Monad (Either e) -- Defined in ‘Data.Either’
instance Monad [] -- Defined in ‘GHC.Base’
...
instance Monad ((->) r) -- Defined in ‘GHC.Base’

That last instance means if I have a function whose first argument is type r, that is a monad.  And if you fill in the types of the various monad functions you would get something like this

(>>=) :: ((->) r) a -> (a -> ((-> r) b) -> ((-> r) b)
(>>=) :: (r -> a) -> (a -> (r -> b)) -> (r -> b) -- simplified
return :: a -> (r -> a)

So in the same way that (IO String) is a Monad and can use do notation, (a -> String) is also a Monad, and can also use do notation.  Hopefully that made sense.

On Fri, Oct 13, 2017 at 2:15 PM, mike h <mike_k_houghton@yahoo.co.uk> wrote:

I have

cap :: String -> String
cap = toUpper

rev :: String -> String
rev = reverse

then I make

tupled :: String -> (String, String)
tupled = do
    r <- rev
    c <- cap
    return (r, c)

and to be honest, yes it’s been a long day at work, and this is coding at home rather than coding (java) at work but
I’m not sure how tupled  works!!!
My first shot was supplying a param s like this

tupled :: String -> (String, String)
tupled s = do
    r <- rev s
    c <- cap s
    return (r, c)

which doesn’t compile. But how does the first version work? How does the string to be processed get into the rev and cap functions??

Thanks

Mike




_______________________________________________
Beginners mailing list
Beginners@haskell.org
http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners