Send Beginners mailing list submissions to
        [email protected]

To subscribe or unsubscribe via the World Wide Web, visit
        http://www.haskell.org/mailman/listinfo/beginners
or, via email, send a message with subject or body 'help' to
        [email protected]

You can reach the person managing the list at
        [email protected]

When replying, please edit your Subject line so it is more specific
than "Re: Contents of Beginners digest..."


Today's Topics:

   1.  Re: Defeating type inference (Will Ness)
   2. Re:  Lambda Functions (Peter Verswyvelen)
   3.  clarification on IO (Michael Easter)
   4. Re:  clarification on IO (Andrew Wagner)


----------------------------------------------------------------------

Message: 1
Date: Fri, 27 Feb 2009 22:59:05 +0000 (UTC)
From: Will Ness <[email protected]>
Subject: [Haskell-beginners] Re: Defeating type inference
To: [email protected]
Message-ID: <[email protected]>
Content-Type: text/plain; charset=us-ascii

Philip Scott <pscott <at> foo.me.uk> writes:

> 
> Hi Alex,
> > The problem is that when you go fro
> >> months = range (Jan,Dec) : months
> >> realmonths = concat months
> >>     

Another way to go about this is to always look at types. You've correctly 
surmised that you have to refer back to the name you're defining, months, in a 
recusive definition, so let's write it down as 
  months = range (Jan,Dec) `somehowJoinWith` months

What is somehowJoinWith's type? Its first argument is [Month], let's call it 
[a]. So
 somehowJoinWith :: [a] -> b -> b

But you want its result to be a list of Month's too. So b = [a] and
 somehowJoinWith :: [a] -> [a] -> [a]

Cons (:) simply won't fit here, as it is :: a -> [a] -> [a].

(++) OTOH does fit, and is exactly what you need.

Thinking with types helps clarify the problem always. It helps us not to 
confuse oranges and boxes-of-oranges. :)

Cheers,



------------------------------

Message: 2
Date: Sat, 28 Feb 2009 00:40:57 +0100
From: Peter Verswyvelen <[email protected]>
Subject: Re: [Haskell-beginners] Lambda Functions
To: Brent Yorgey <[email protected]>
Cc: [email protected]
Message-ID:
        <[email protected]>
Content-Type: text/plain; charset="iso-8859-1"

On Fri, Feb 27, 2009 at 6:31 PM, Brent Yorgey <[email protected]>wrote:

> The only disadvantage is that some things you might expect to be
> constants will actually get recomputed every time they are used. For
> example, suppose you define
>
>  foo = very expensive computation involving a bunch of numbers
>
> You might think that foo will get computed just once, the first time
> it is needed.  However, if foo ends up with a polymorphic type, like,
> say
>
>  foo :: Num a => a
>
> then it is not actually a constant, but a function which takes a Num
> dictionary (i.e. a record of the Num methods) as an argument.  So it
> will be recomputed every time it is used, since it might have
> different values for different types.


Yes indeed. Beginners might want to verify this with the following little
program (just assume 42 takes a very long to compute, on some alien computer
this took 7½ million years ;-)

import Debug.Trace

foo :: Num a => a
foo = trace "foo" $ 42

bar :: Int
bar = trace "bar" $ 42

When evaluating foo (e.g in GHCi) "foo" will be printed every time, bar only
once.

I guess a clever implementation would only compute foo once for each
different type of a? But then of course you'll hit a runtime performance
penalty every time when accessing foo since this will require a lookup...
Mmm, this feels as a case where you can't determine at compile time if a
function - in this case a polymorphic CAF - will need memoization or not...

For example (just a quick hack)

import           Data.Typeable
import           Data.IORef
import qualified Data.IntMap as M
import           System.IO.Unsafe
import           Debug.Trace

fooCache :: IORef (M.IntMap a)
fooCache = unsafePerformIO $ newIORef M.empty

foo :: (Typeable a, Num a) => a
foo = unsafePerformIO $ do
        key <- typeRepKey (typeOf value)
        atomicModifyIORef fooCache (updateCache key)
  where
    value = trace "foo is computed" $ 42
    updateCache key cache =
      case key `M.lookup` cache of
        Just n -> (cache, trace "foo is cached" n)
        Nothing -> (M.insert key value cache, value)



Now, you might wonder why this is such a big deal.  The answer is: it
> isn't.  I have the MR automatically turned off in my .ghci file, and
> I've never missed it.  Furthermore, the monomorphism restriction will
> be removed in the next version of the Haskell language standard.


Cool. But I guess the next version of the standard will take a while? :)
-------------- next part --------------
An HTML attachment was scrubbed...
URL: 
http://www.haskell.org/pipermail/beginners/attachments/20090228/91955b29/attachment-0001.htm

------------------------------

Message: 3
Date: Fri, 27 Feb 2009 20:50:21 -0600
From: Michael Easter <[email protected]>
Subject: [Haskell-beginners] clarification on IO
To: [email protected]
Message-ID:
        <[email protected]>
Content-Type: text/plain; charset="iso-8859-1"

Folks,

I've been reading RWH and this
http://www.haskell.org/haskellwiki/IO_inside#Haskell_is_a_pure_language

I think I understand monads. I think I understand how IO is much different
from, e.g. Maybe, State, etc.

However there are some turns of phrase with respect to IO that have me
baffled.  I am giving a presentation
on monads next week, and hope you can help. (I'm not quite as lost as this
might imply!)

Q1: The web page mentions that normal Haskell functions cannot cause
side-effects, yet later talks about
side-effects with putStrLn. I assume the key point here that IO actions are,
by definition, _not_ normal functions?


Q2: Is it true to say that *any* monadic action *could *cause side-effects,
depending on the design of that
monad? i.e. Does one generalize from the IO monad to (possibly) an arbitrary
monad? *Musing* This must be true as
using State must surely be considered a side-effect.


Q3: The web page mentions IO as being a baton, or token, that is used to
thread/order the actions. Is true
that this is merely one simple perspective, with respect to order of
evaluation? This is hard to articulate,
but it seems to me that "in the IO monad" there is a large subsystem of
(inaccessible) state, machinery, etc.
Is it really a token?

Q4: Is the following idea accurate: a Haskell program is partitioned into 2
spaces. One is a sequence
of IO actions; the other is a space of pure functions and 'normal' Haskell
operations.  The execution of a
program begins with the main :: IO () action and, effectively, crosses from
one space to the other. In the
pure space, the math-like functions can be highly optimized but only insofar
as they do not disrupt the
implied order of the IO actions.  Because of the type system, the program
recognizes when it enters
"back" into the IO space and follows different, less optimized rules.

My concern is that the above is *not* accurate, but I don't know why.


thanks so much for your help
Michael Easter

-- 
----------------------
Michael Easter
http://codetojoy.blogspot.com: Putting the thrill back in blog

http://youtube.com/ocitv -> Fun people doing serious software engineering
-------------- next part --------------
An HTML attachment was scrubbed...
URL: 
http://www.haskell.org/pipermail/beginners/attachments/20090227/9c250695/attachment-0001.htm

------------------------------

Message: 4
Date: Fri, 27 Feb 2009 22:30:39 -0500
From: Andrew Wagner <[email protected]>
Subject: Re: [Haskell-beginners] clarification on IO
To: Michael Easter <[email protected]>
Cc: [email protected]
Message-ID:
        <[email protected]>
Content-Type: text/plain; charset="iso-8859-1"

I'll take a shot at answering some of your questions by explaining how I
understand it, and we'll see if it helps or makes it worse.

Let's talk about monads first. Monads can be thought of as a way of sort of
hiding "side effects". That is, there is nothing inherently impure about
monads. The "side effects" happen in the bind function, essentiall. For
example, in the case of state, the state is carried from one function to
another. The bind function actually says how to do this; You just don't
usually see it because it's "hidden" in the do notation. In the Maybe
function, the plumbing hides the fact that we quit at any point the
computation fails, and so on. So while in an impure language, any statement
can have any side effect, in haskell, if you know what monad you're in, you
know exactly what the "side effect" will occur - which means, it's not
really a side effect at all, but part of the actual intended effect.

Now for IO. You can think of IO as being essentially State RealWorld. That
is, every operation is dependent on the entire state of the world, including
what you're thinking, and what kind of bug is crawling on the 18th blade of
grass in your yard. If we could actually represent the whole world this way,
Haskell would truly be a completely pure language. The only reason IO, and
thus Haskell, is impure at all, is because we can't literally represent the
whole world. EVERYTHING ELSE, INCLUDING EVERY OTHER TYPE OF MONADIC ACTION
IN HASKELL, is completely pure.

Ok, so let's address your questions a little more specifically.

Q1: The web page mentions that normal Haskell functions cannot cause
> side-effects, yet later talks about
> side-effects with putStrLn. I assume the key point here that IO actions
> are, by definition, _not_ normal functions?
>

Right, IO actions can have side effects because they can take into account,
and modify, the RealWorld.


> Q2: Is it true to say that *any* monadic action *could *cause
> side-effects, depending on the design of that
> monad? i.e. Does one generalize from the IO monad to (possibly) an
> arbitrary monad? *Musing* This must be true as
> using State must surely be considered a side-effect.
>

Again, yes, this is accurate, but it's different from most impure languages
in that the side effect is completely baked in by the monad you're in, so
that you can't really say that the effect is a "side effect" at all.


> Q3: The web page mentions IO as being a baton, or token, that is used to
> thread/order the actions. Is true
> that this is merely one simple perspective, with respect to order of
> evaluation? This is hard to articulate,
> but it seems to me that "in the IO monad" there is a large subsystem of
> (inaccessible) state, machinery, etc.
> Is it really a token?
>

Again, in many ways, it's easier to think of the IO monad as a state monad.
In that sense, the state of the world is indeed being passed from one action
to the next, as defined by bind. That's the inaccessible state machinery I
suspect you're sensing.


> Q4: Is the following idea accurate: a Haskell program is partitioned into 2
> spaces. One is a sequence
> of IO actions; the other is a space of pure functions and 'normal' Haskell
> operations.  The execution of a
> program begins with the main :: IO () action and, effectively, crosses from
> one space to the other. In the
> pure space, the math-like functions can be highly optimized but only
> insofar as they do not disrupt the
> implied order of the IO actions.  Because of the type system, the program
> recognizes when it enters
> "back" into the IO space and follows different, less optimized rules.
>

I think it would be easier to talk about haskell in terms of pure and impure
code. All Haskell code is pure except for IO. Pure functions are easier to
reason about and to optimize, because you don't have to take into account
the RealWorld state, or other possible, REAL side effects..


> My concern is that the above is *not* accurate, but I don't know why.
>
>
> thanks so much for your help
> Michael Easter
>
> --
> ----------------------
> Michael Easter
> http://codetojoy.blogspot.com: Putting the thrill back in blog
>
> http://youtube.com/ocitv -> Fun people doing serious software engineering
>
> _______________________________________________
> Beginners mailing list
> [email protected]
> http://www.haskell.org/mailman/listinfo/beginners
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: 
http://www.haskell.org/pipermail/beginners/attachments/20090227/15ec3af9/attachment.htm

------------------------------

_______________________________________________
Beginners mailing list
[email protected]
http://www.haskell.org/mailman/listinfo/beginners


End of Beginners Digest, Vol 8, Issue 29
****************************************

Reply via email to