Re: [Haskell-cafe] Network.CGI -- practical web programming example.

2009-07-02 Thread wren ng thornton

Brandon S. Allbery KF8NH wrote:
Some Haskell 
programmers use fmap (because most Monads are also Functors), others use 
liftM.  Both have the same effect:  given a monadic computation m a, 
liftM f turns f into a function that operates on the enclosed a 
instead of the entire m a.


That is, given the theory behind it all, every monad is a functor (note 
the lower case); from which it follows that liftM == fmap. For 
historical reasons the Monad typeclass does not require a Functor 
instance, however, and so it's not the case that every Monad is also a 
Functor (note the upper case).


The function liftM can be defined generically given definitions for 
return and (=), so some prefer to use liftM to avoid the extra Functor 
dependency. The function fmap can be given specialized definitions due 
to overloading, so others prefer to use it for efficiency reasons. The 
($) function is just a symbolic name for fmap.



You'll also see the Applicative typeclass for applicative functors. 
Applicative does require a Functor instance, which is good. (And 
actually, every monad is an applicative functor; though the Monad class 
doesn't require Applicative either.) The function liftA can be defined 
generically given definitions for pure and (*), and liftA == fmap as 
well. The only reason anyone should use liftA is for defining a Functor 
instance when they're too lazy to give a specialized implementation.



--
Live well,
~wren
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Network.CGI -- practical web programming example.

2009-07-02 Thread Brandon S. Allbery KF8NH

On Jul 2, 2009, at 17:59 , wren ng thornton wrote:

Brandon S. Allbery KF8NH wrote:
Some Haskell programmers use fmap (because most Monads are also  
Functors), others use liftM.  Both have the same effect:  given a  
monadic computation m a, liftM f turns f into a function that  
operates on the enclosed a instead of the entire m a.


That is, given the theory behind it all, every monad is a functor  
(note the lower case); from


Yeh, I decided to bypass the whole all monads are functors, but for  
Hysterical Raisins not all Monads are Functors morass.


--
brandon s. allbery [solaris,freebsd,perl,pugs,haskell] allb...@kf8nh.com
system administrator [openafs,heimdal,too many hats] allb...@ece.cmu.edu
electrical and computer engineering, carnegie mellon universityKF8NH




PGP.sig
Description: This is a digitally signed message part
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Network.CGI -- practical web programming example.

2009-06-27 Thread Luke Palmer
Your code examples are:

On Sat, Jun 27, 2009 at 6:07 PM, Edward Ing edward@gmail.com wrote:

 saveFile n =
do  cont - (liftM fromJust) $ getInputFPS file
 let f = uploadDir ++ / ++ basename n
 liftIO $ BS.writeFile f cont
 return $ paragraph  (Saved as  +++ anchor ! [href f]  f +++
 .)


Vs.


 saveFile n =
 do   cont - getInputFPS file
let f = uploadDir ++ / ++ basename n
   liftIO $ BS.writeFile f (fromJust cont)
   return $ paragraph  (Saved as  +++ anchor ! [href f]  f +++
 .)


Consider the line x - y in a do expression.  If y has type M a for some
monad M, then x has type a.

So, let's say you have a value f :: Maybe Int, and you want to return the
Int's stringification if it exists.  We can write this in these two ways:

do x - f
   return (show x)

do x - liftM show f
   return x

liftM :: (a - b) - (M a - M b)   for any monad M.  That means if you want
to apply a function to a value which is currently wrapped in a monad
constructor, you need to lift it in.  liftM takes a function on ordinary
values to a function on wrapped values.  But *after* you bind, you don't
need to lift anymore.

Which of the two above styles to choose is a matter of style, and, in my
code at least, varies from situation to situation.

That said, you can write both of these snippets as fmap show f or show
$ f  (where ($) is from Control.Applicative), which is how it would be
done in practice.

Does that make sense?
Luke
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Network.CGI -- practical web programming example.

2009-06-27 Thread Brandon S. Allbery KF8NH

On Jun 27, 2009, at 20:07 , Edward Ing wrote:

saveFile n =
   do  cont - (liftM fromJust) $ getInputFPS file
let f = uploadDir ++ / ++ basename n
liftIO $ BS.writeFile f cont
return $ paragraph  (Saved as  +++ anchor ! [href f]   
f +++ .)


saveFile n =
do   cont - getInputFPS file
   let f = uploadDir ++ / ++ basename n
  liftIO $ BS.writeFile f (fromJust cont)
  return $ paragraph  (Saved as  +++ anchor ! [href f]  f + 
++ .)


1) Why did the author choose to insert liftM in function saveFile?



It's because of where fromJust is being called.  In yours, it's being  
used at a place that expects a normal value, so you can just go ahead  
and use it.


The original is applying the fromJust inside of a monadic computation,  
as indicated by the (-), so it needs to be lifted.  Some Haskell  
programmers use fmap (because most Monads are also Functors), others  
use liftM.  Both have the same effect:  given a monadic computation m  
a, liftM f turns f into a function that operates on the enclosed  
a instead of the entire m a.


--
brandon s. allbery [solaris,freebsd,perl,pugs,haskell] allb...@kf8nh.com
system administrator [openafs,heimdal,too many hats] allb...@ece.cmu.edu
electrical and computer engineering, carnegie mellon universityKF8NH




PGP.sig
Description: This is a digitally signed message part
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe