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: clarification on IO (Will Ness)
2. Re: Finite State Machine .. (Heinrich Apfelmus)
3. Re: Re: clarification on IO (Gregg Reynolds)
4. Re: clarification on IO (Will Ness)
5. Re: clarification on IO (Will Ness)
6. Re: Re: Finite State Machine .. (Tom Poliquin)
7. let indenting problems (7stud)
8. Re: let indenting problems (Miguel Pignatelli)
----------------------------------------------------------------------
Message: 1
Date: Sun, 1 Mar 2009 10:28:24 +0000 (UTC)
From: Will Ness <[email protected]>
Subject: [Haskell-beginners] Re: clarification on IO
To: [email protected]
Message-ID: <[email protected]>
Content-Type: text/plain; charset=utf-8
Michael Easter <codetojoy <at> gmail.com> writes:
>
>
> Thanks Andrew, this is really great...My main revelation here is that a "side-
effect" in other monads is still pure. e.g. The Logger example in RWH builds
up a list of log strings "behind the scenes" but this is much different than
writing to disk, or launching missiles, to quote SP Jones.
May be this is exactly how we ought to look at the IO monad - as a Logger
monad? Each IO-bound chain of action-functions defining an IO value that holds
a record of what it is the IO primitives that we used promised us they will do
when run by the system.
That's it.
(?)
After all, we can have a definition of such a value, and have it run multiple
times for us, so _as definition_ it's no different than any other definition in
Haskell. It's just that _its value_ can cause the system to actually perform
these IO actions in some circumstances.
As for terminology: we've got to have some special name for functions that are
chainable by bind. Calling them actions confuses them with the real world
actions performed by IO.
May be to call them "action functions"?
------------------------------
Message: 2
Date: Sun, 01 Mar 2009 11:31:45 +0100
From: Heinrich Apfelmus <[email protected]>
Subject: [Haskell-beginners] Re: Finite State Machine ..
To: [email protected]
Message-ID: <[email protected]>
Content-Type: text/plain; charset=ISO-8859-1
Tom Poliquin wrote:
>
> 1) Is there a nice (canonical) way of eliminating
> nested evil in Haskell? I thought that perhaps making
> a tuple of all the if's conditions and patterm matching
> on them might make a bit more comprehensible.
> Likely there's a better way.
You probably want guards, like this
fib n
| n == 0 = 0
| n == 1 = 1
| otherwise = fib (n-1) + fib (n-2)
Regards,
apfelmus
--
http://apfelmus.nfshost.com
------------------------------
Message: 3
Date: Sun, 1 Mar 2009 08:57:04 -0600
From: Gregg Reynolds <[email protected]>
Subject: Re: [Haskell-beginners] Re: clarification on IO
To: Will Ness <[email protected]>
Cc: [email protected]
Message-ID:
<[email protected]>
Content-Type: text/plain; charset="utf-8"
On Sun, Mar 1, 2009 at 4:28 AM, Will Ness <[email protected]> wrote:
> Michael Easter <codetojoy <at> gmail.com> writes:
> ...
> After all, we can have a definition of such a value, and have it run
> multiple
> times for us, so _as definition_ it's no different than any other
> definition in
> Haskell. It's just that _its value_ can cause the system to actually
> perform
> these IO actions in some circumstances.
But it isn't a definition. "Reference" would be better; "getChar" is a term
that references a value.
>
> As for terminology: we've got to have some special name for functions that
> are
> chainable by bind. Calling them actions confuses them with the real world
> actions performed by IO.
>
Correction: special name for IO "functions" (actually "IO terms" would be
better). The monad just organizes stuff, so the IO monad, as monad, is no
different than any other monad.
>
> May be to call them "action functions"?
>
This was a big problem for me; I find terms like "action", "computation",
"function" completely misleading for IO terms/values. You might find
"Computation"
considered harmful. "Value" not so hot
either<http://syntax.wikidot.com/blog:5>useful; see also the comment
"Another try at the key sentence". There are a
few other articles on the blog that address this terminology problem.
-gregg
-------------- next part --------------
An HTML attachment was scrubbed...
URL:
http://www.haskell.org/pipermail/beginners/attachments/20090301/e0ccb0b8/attachment-0001.htm
------------------------------
Message: 4
Date: Sun, 1 Mar 2009 17:59:38 +0000 (UTC)
From: Will Ness <[email protected]>
Subject: [Haskell-beginners] Re: clarification on IO
To: [email protected]
Message-ID: <[email protected]>
Content-Type: text/plain; charset=utf-8
Gregg Reynolds <dev <at> mobileink.com> writes:
> On Sun, Mar 1, 2009 at 4:28 AM, Will Ness <will_n48 <at> yahoo.com> wrote:
>
>
> Michael Easter <codetojoy <at> gmail.com> writes:
> ...
> After all, we can have a definition of such a value, and have it run multiple
> times for us, so _as definition_ it's no different than any other definition
in
> Haskell. It's just that _its value_ can cause the system to actually perform
> these IO actions in some circumstances.
>
> But it isn't a definition. "Reference" would be better; "getChar" is a term
that references a value.
Excuse me for being too brief. I was talking about the definitions of IO
values, of type (IO a), viz. the do-block (or bind-chain) definitions, as in
let v=do { getChar; putStrLn "12"; return 2 }
that are just regular Haskell defintions, from inside the Haskell world POV.
The IO-action functions involved here would be
getChar
(\_-> putStrLn "12")
(\_-> return 2)
These IO-action functions, chaind by IO bind, create a combined-actions IO
value, in this case of type (:: Num a => IO a).
The IO-action is not the I/O operation in the real world, but an action of
recording a promise to perform it.
Any IO primitive can be seen as latching this hidden promise onto its explicit
return value, thus creating a monadic value (:: IO a), carrying along this
hidden promise. IO bind combines these promises into a combined record, or log,
of promises to perform actual I/O activity, if called upon by the system.
That recording of a promise is the IO-action that IO monad is about, from pure
Haskell standpoint.
Another monad will have another meaning for its actions, latching another
hidden data on their results, but they still can be seen as actions, in context
of being sequenced and combined by that monad's bind.
Haskell will also attempt to reduce and simplify this combined actions value,
unlike in IO case where it can't do that because the values involved can change
from one invocation to another.
So seen from inside the pure Haskell world IO monad is just another Logging
Monad, building logs of future activity to be performed. And it can be
performed more than once, of course:
Prelude> let v=do{ getChar; putStrLn "12"; return () }
Prelude> [v]
[<<IO action>>] :: [IO ()]
Prelude> v
c12
Prelude> v
d12
Prelude>
> As for terminology: we've got to have some special name for functions that are
> chainable by bind. Calling them actions confuses them with the real world
> actions performed by IO.
What I seek here is to demystify the monad, any monad, and IO monad in
particular, and for that a clear and consisent terminology must be employed. We
should be able to name things, in English, that we talk about - in English.
> Correction:Â special name for IO "functions" (actually "IO terms" would be
better).Â
Why? They are just fuctions, of type (Monad m => a -> m b). What I'm saying,
they are of special type, chainable by the M monad, so it seems logical to have
a special name for such M-chainable functions, e.g. "M-action functions"
(whatever the M).
The monad M is chaining and combining something. It is M-action functions, of
type (a -> M b), that get chained by its bind, and their hidden data combined
by it, behind the curtain.
Usually when we have a name for some concept, it becomes clearer. And vice
versa.
> The monad just organizes stuff, so the IO monad, as monad, is no different
than any other monad.
>
>
>
> May be to call them "action functions"?
>
>
> This was a big problem for me; I find terms
like "action", "computation", "function" completely misleading for IO
terms/values.Â
Why? A function of type (a -> M b) is a function that returns a value, (:: M
b), tagged with some monadic hidden data. In case of IO, it is a promise to
perform some actual I/O that's passed around, hidden. But the M-action function
itself is just a regular Haskell function. It can be defined elsewhere,
anywhere.
IO values themselves are no mystery too. They just carry along with them a log
of promised I/O activity as specified at time of their creation (definition).
> You might find ["Computation" considered harmful. "Value" not so hot either]
useful; see also the comment "Another try at the key sentence". There are a
few other articles on the blog that address this terminology problem.
Thank you. Will do.
------------------------------
Message: 5
Date: Mon, 2 Mar 2009 02:28:18 +0000 (UTC)
From: Will Ness <[email protected]>
Subject: [Haskell-beginners] Re: clarification on IO
To: [email protected]
Message-ID: <[email protected]>
Content-Type: text/plain; charset=utf-8
Gregg Reynolds <dev <at> mobileink.com> writes:
>
>
>> On Sun, Mar 1, 2009 at 4:28 AM, Will Ness <will_n48 <at> yahoo.com> wrote:
>>
>>
>> Michael Easter <codetojoy <at> gmail.com> writes:
>> ...
>> It's just that _its value_ can cause the system to actually perform
>> these IO actions in some circumstances.
>>
>>
>> May be to call them "action functions"?
>
>
> This was a big problem for me; I find terms
like "action", "computation", "function" completely misleading for IO
terms/values. You might find ["Computation" considered harmful. "Value" not so
hot either] useful; see also the comment "Another try at the key sentence".
There are a few other articles on the blog that address this terminology
problem.
Have read it now. Didn't like the formulation in that comment though. It's
mixing together issues of monad in general and IO in particular when it speaks
of "side-effects" being attached "to a value".
No value has side-effects in Haskell. There are no side effects in Haskell.
There are no values in Haskell either, only expressions denoting values. (1+
(1+1)) , (1+2), 3 - it's all the same, and nothing precludes Haskell
implementation from actually exchanging one with another right away.
Here's one possible sketch-out of IO monad to clarify what I mean:
data IO a = IORec -> (a,IORec) -- record of I/O activities to be performed
instance Monad IO where
return a rec = (a,rec) -- return :: a -> IO a
(m »= g) rec = uncurry g $ m rec -- g :: a -> IO b
putStrLn :: a -> IO ()
putStrLn a rec = ((),rec ++ [("putStrLn", a)])
Thus it is all just pure Haskell, building a record of I/O requests that can
get executed "on the outside" by the run-time system. Being defined once, it
can be run several times, or none at all.
This is exactly like your idea on that log you mentioned about separating the
pure Haskell world and the "outer" impure world of I/O - or IOW, pure
compiler's world and run-time system.
------------------------------
Message: 6
Date: Sun, 1 Mar 2009 22:28:27 -0800
From: Tom Poliquin <[email protected]>
Subject: Re: [Haskell-beginners] Re: Finite State Machine ..
To: [email protected]
Message-ID: <[email protected]>
Content-Type: text/plain; charset="iso-8859-1"
> > I'm working on a project (in Haskell) and was
> > given some old Java code to indicate the required
> > functionality for a particular function. It's a page of
> > nested (4 deep) if statements. (That's probably
> > why they gave me the code, no one could
> > describe it).
> > 1) Is there a nice (canonical) way of eliminating
> > nested evil in Haskell?
> >2) If an FSM is appropriate is there a 'standard'
> > Haskell FSM implementation?
> > It actually seems like a fun problem .. if I
> > had the time ..
Andrew Wagner wrote:
> This does sound interesting. Can you provide (at least some of) the code?
As I thought it would violate the group mores I didn't include the Java
code here .. :-) It's at
http://www.softcomp.com/pastes/ifexample.java
This is a typical module .. others are worse.
Heinrich Apfelmus wrote:
> You probably want guards, like this
> fib n
> | n == 0 = 0
> | n == 1 = 1
> | otherwise = fib (n-1) + fib (n-2)
Is this what you had in mind?
module Main where
foo a b c
| p1 && p2 || not p3 = 42
| p1 || not p2 && p3 = 13
| otherwise = 0
where
-- setup if predicates
p1 = a > b
p2 = a + b > 2
p3 = a - b < 1
main = do
x <- return $ foo 9 2 3
print x
-- 42
Thanks,
Tom
------------------------------
Message: 7
Date: Mon, 2 Mar 2009 08:51:39 +0000 (UTC)
From: 7stud <[email protected]>
Subject: [Haskell-beginners] let indenting problems
To: [email protected]
Message-ID: <[email protected]>
Content-Type: text/plain; charset=us-ascii
I get indenting errors with the following attempts to use let:
-----
import Data.List (sortBy)
mySort xs = sortBy myCompare xs
let lx = length x
ly = length y
in where myCompare x y
| lx < ly = LT
| lx == ly = EQ
| lx > ly = GT
------------------
import Data.List (sortBy)
mySort xs = sortBy myCompare xs
where myCompare x y
let lx = length x
ly = length y
in
| lx < ly = LT
| lx == ly = EQ
| lx > ly = GT
-------------
import Data.List (sortBy)
mySort xs = sortBy myCompare xs
where myCompare x y
let lx = length x
ly = length y
in | lx < ly = LT
| lx == ly = EQ
| lx > ly = GT
-------------
This is what I ended up with:
-------
import Data.List (sortBy)
mySort xs = sortBy myCompare xs
where myCompare x y
| lx < ly = LT
| lx == ly = EQ
| lx > ly = GT
where lx = length x
ly = length y
-------
But I would like to know how to use let.
------------------------------
Message: 8
Date: Mon, 02 Mar 2009 10:46:23 +0100
From: Miguel Pignatelli <[email protected]>
Subject: Re: [Haskell-beginners] let indenting problems
To: 7stud <[email protected]>
Cc: [email protected]
Message-ID: <[email protected]>
Content-Type: text/plain; charset=ISO-8859-1; format=flowed
What about...
mySort xs = let myCompare x y
| lx < ly = LT
| lx == ly = EQ
| lx > ly = GT
where
lx = length x
ly = length y
in sortBy myCompare xs
M;
7stud wrote:
> I get indenting errors with the following attempts to use let:
>
> -----
> import Data.List (sortBy)
>
> mySort xs = sortBy myCompare xs
> let lx = length x
> ly = length y
> in where myCompare x y
> | lx < ly = LT
> | lx == ly = EQ
> | lx > ly = GT
>
> ------------------
>
> import Data.List (sortBy)
>
> mySort xs = sortBy myCompare xs
> where myCompare x y
> let lx = length x
> ly = length y
> in
>
> | lx < ly = LT
> | lx == ly = EQ
> | lx > ly = GT
>
> -------------
>
> import Data.List (sortBy)
>
> mySort xs = sortBy myCompare xs
> where myCompare x y
> let lx = length x
> ly = length y
> in | lx < ly = LT
> | lx == ly = EQ
> | lx > ly = GT
>
> -------------
>
>
> This is what I ended up with:
>
> -------
> import Data.List (sortBy)
>
> mySort xs = sortBy myCompare xs
> where myCompare x y
> | lx < ly = LT
> | lx == ly = EQ
> | lx > ly = GT
> where lx = length x
> ly = length y
> -------
>
> But I would like to know how to use let.
>
>
>
>
>
> _______________________________________________
> Beginners mailing list
> [email protected]
> http://www.haskell.org/mailman/listinfo/beginners
>
------------------------------
_______________________________________________
Beginners mailing list
[email protected]
http://www.haskell.org/mailman/listinfo/beginners
End of Beginners Digest, Vol 9, Issue 2
***************************************