Re: [Haskell-cafe] Re: Do expression definition

2010-09-15 Thread wren ng thornton

On 9/13/10 6:22 AM, Michael Lazarev wrote:

Thanks for examples and pointers.

Since I came from Lisp, it never occurred to me that let and lambda
are different constructs in Haskell.
I thought that
 let x = y in f
is really
 (\x -  f) y
It turns out that let is about declarations which are not the same as
function applications above.


Right. This is a common mistake for people coming from Lisp, Scheme, and 
other untyped lambda calculi. In the untyped world it's fine to conflate 
let and lambda, because they only differ in how they're typed (and if 
you have no types...).


The difference is that, for let-bindings, once you've figured out a type 
of the variable being bound, then that type can be generalized. The 
exact process of generalization has some subtle details to watch out 
for, but suffice it to say that certain type variables are allowed to 
become universally quantified. Which means that you're allowed to use x 
at different types within f, provided all those different types are 
consistent with the generalized type.


Whereas, lambda-bindings don't get generalized, and so they'll always be 
monomorphic (assuming Hindley--Milner inference without extensions like 
-XRankNTypes). This is necessary in order to catch numerous type errors, 
though Haskell lets you override this behavior by giving an explicitly 
polymorphic type signature if you have -XRankNTypes enabled.


...

FWIW, a lot of the tricky details about generalization come from the way 
that Hindley--Milner inference is usually described. That is, since HM 
only allows prenex universal quantification, the quantifiers are usually 
left implicit. This in turn means it's not always clear when the 
unification variables used in type inference are actual type variables 
vs not. If we assume System F types instead and make all the quantifiers 
explicit, then it becomes much easier to explain the generalization 
process because we're being explicit about where variables are bound.


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


[Haskell-cafe] Re: Do expression definition

2010-09-13 Thread Gleb Alexeyev

On 09/13/2010 12:23 PM, Michael Lazarev wrote:

2010/9/13 Henning Thielemannlemm...@henning-thielemann.de:

It means that variables bound by let, may be instantiated to different types
later.


Can you give an example, please?


testOk = let f = id in (f 42, f True)

--testNotOk :: Monad m = m (Int, Bool)
--testNotOk = do f - return id
--   return (f 42, f True)

Try uncommenting the 'testNotOk' definition.

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Re: Do expression definition

2010-09-13 Thread Thomas Davie

On 13 Sep 2010, at 10:28, Gleb Alexeyev wrote:

 On 09/13/2010 12:23 PM, Michael Lazarev wrote:
 2010/9/13 Henning Thielemannlemm...@henning-thielemann.de:
 It means that variables bound by let, may be instantiated to different types
 later.
 
 Can you give an example, please?
 
 testOk = let f = id in (f 42, f True)
 
 --testNotOk :: Monad m = m (Int, Bool)
 --testNotOk = do f - return id
 --   return (f 42, f True)
 
 Try uncommenting the 'testNotOk' definition.

There's no later here at all.

Two seperate definitions in a Haskell program act as if they have always been 
defined, are defined, and always will be defined, they are not dealt with in 
sequence (except for pattern matching but that doesn't apply here).

Instead, what's going on here is scoping.  The f in testOk is a different f to 
the one in testNotOkay, distinguished by their scope.

Finally, this is not how you use a let in a do expression, here's how you 
should do it:

testOk2 :: Monad m = m (Int, Bool)
testOk2 = do let f = id
 return (f 42, f True)


Thanks

Tom Davie___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] Re: Do expression definition

2010-09-13 Thread Gleb Alexeyev

On 09/13/2010 12:38 PM, Thomas Davie wrote:


On 13 Sep 2010, at 10:28, Gleb Alexeyev wrote:


On 09/13/2010 12:23 PM, Michael Lazarev wrote:

2010/9/13 Henning Thielemannlemm...@henning-thielemann.de:

It means that variables bound by let, may be instantiated to different types
later.


Can you give an example, please?


testOk = let f = id in (f 42, f True)

--testNotOk :: Monad m =  m (Int, Bool)
--testNotOk = do f- return id
--   return (f 42, f True)

Try uncommenting the 'testNotOk' definition.


There's no later here at all.

Two seperate definitions in a Haskell program act as if they have always been 
defined, are defined, and always will be defined, they are not dealt with in 
sequence (except for pattern matching but that doesn't apply here).

Instead, what's going on here is scoping.  The f in testOk is a different f to 
the one in testNotOkay, distinguished by their scope.

Finally, this is not how you use a let in a do expression, here's how you 
should do it:

testOk2 :: Monad m =  m (Int, Bool)
testOk2 = do let f = id
  return (f 42, f True)



I don't understand, I'm afraid. Michael Lazarev asked for example on the 
difference between let-bound and lambda-bound values. testNotOk 
definition mirrors the structure of the testOk definition, but testNotOk 
is, pardon my pun, not ok, because f is let-bound and, therefore, 
monomorphic, while f in the first definition is polymorphic.


I never implied that definitions are processed in some sort of sequence, 
nor I stated that the two f's are somehow related.


Thanks

Tom Davie



___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Re: Do expression definition

2010-09-13 Thread Henning Thielemann


On Mon, 13 Sep 2010, Gleb Alexeyev wrote:


On 09/13/2010 12:38 PM, Thomas Davie wrote:


There's no later here at all.

Two seperate definitions in a Haskell program act as if they have always 
been defined, are defined, and always will be defined, they are not dealt 
with in sequence (except for pattern matching but that doesn't apply here).


I don't understand, I'm afraid. Michael Lazarev asked for example on the 
difference between let-bound and lambda-bound values. testNotOk definition 
mirrors the structure of the testOk definition, but testNotOk is, pardon my 
pun, not ok, because f is let-bound and, therefore, monomorphic, while f in 
the first definition is polymorphic.


I never implied that definitions are processed in some sort of sequence, nor 
I stated that the two f's are somehow related.


I think the later refered to my words. With later I meant somewhere 
below the binding in the do-block.

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] Re: Do expression definition

2010-09-13 Thread Gleb Alexeyev

On 09/13/2010 12:45 PM, Gleb Alexeyev wrote:


is, pardon my pun, not ok, because f is let-bound and, therefore,
monomorphic


This line doesn't make sense, I was too hasty to hit the 'Send' button, 
I meant to write 'lambda-bound', of course, apologies for that.





___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Re: Do expression definition

2010-09-13 Thread Michael Lazarev
Thanks for examples and pointers.

Since I came from Lisp, it never occurred to me that let and lambda
are different constructs in Haskell.
I thought that
let x = y in f
is really
(\x - f) y
It turns out that let is about declarations which are not the same as
function applications above.

So, here is a little followup for this experiment.

Prelude :t (\f - (f 42, f True))

interactive:1:10:
No instance for (Num Bool)
  arising from the literal `42' at interactive:1:10-11
Possible fix: add an instance declaration for (Num Bool)
In the first argument of `f', namely `42'
In the expression: f 42
In the expression: (f 42, f True)

If I understand correctly, compiler first checks f 42, and deduces
that f must be of type (Num a) = a - b.
Then it checks f True, and it does not satisfy the previously deduced
type for f, because type of True is not in Num class.



This works:

Prelude :t (\f - (f 42, f 41.9))
(\f - (f 42, f 41.9)) :: (Fractional t1) = (t1 - t) - (t, t)

It just managed to deduce a type for f :: (Fractional t1) = (t1 - t)



And this, of course, works:

Prelude let f = id in (f 42, f True)
(42,True)

If I understand correctly again, it happens because f is a definition,
which gets substituted to f 42 and to f True.
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] Re: Do expression definition

2010-09-13 Thread Paolo G. Giarrusso
On Sep 13, 12:22 pm, Michael Lazarev lazarev.mich...@gmail.com
wrote:
 Thanks for examples and pointers.

 Since I came from Lisp, it never occurred to me that let and lambda
 are different constructs in Haskell.

You're not alone, I didn't believe my eyes when I first read about the
difference (I learned Scheme, but the difference doesn't really matter
here)

 Prelude :t (\f - (f 42, f True))

 interactive:1:10:
     No instance for (Num Bool)
[...]
 If I understand correctly, compiler first checks f 42, and deduces
 that f must be of type (Num a) = a - b.
 Then it checks f True, and it does not satisfy the previously deduced
 type for f, because type of True is not in Num class.

That's a reasonable explanation - I don't know details about the
order, and
 :t (\f - (f True, f 42))
gives the same mistake; I believe that type-checking is still in order
(left-to-right or right-to-left, we can't say) but whether (Num t) and
Bool is deduced first does not matter, because unifying them is
commutative.

 This works:

 Prelude :t (\f - (f 42, f 41.9))
 (\f - (f 42, f 41.9)) :: (Fractional t1) = (t1 - t) - (t, t)

 It just managed to deduce a type for f :: (Fractional t1) = (t1 - t)

Yes, but that's not polymorphic in the sense people are using - ghc
searched for a common type, and realized that there's a whole class of
types where both 42 and 41.9 belong - Fractional.

 And this, of course, works:

 Prelude let f = id in (f 42, f True)
 (42,True)

 If I understand correctly again, it happens because f is a definition,
 which gets substituted to f 42 and to f True.

Almost true. In evaluating let a = b, b must be evaluated before
binding it to a, and a value has a type. Actually, one can define the
substitution semantics you describe, but interesting things happen
then. Section 22.7 of Types and Programming Languages from Pierce
discusses exactly this, in the context of ML* - I guess you can also
Google for let-polymorphism.

The real thing is that when you write let f = id in, the type of a
is deduced (internally a - a), and then generalized (internally
forall a. a - a). The difference is that in the first case, GHC
will try to discover what type a is by unifying it with the type of
arguments of f - unification would produce type equations a = Int, a
= Bool in the above example. The forall prevents that. Note that I
wrote internally, even if you can actually write both types (the
second with an extension, IIRC) because in many cases when you write a
top-level type-signature:
f :: a - a
that is also implicitly generalized.

* Note that in the end Pierce explains a problem with polymorphic
references and its solution, but this does not applies to Haskell
because of the lack of side effects (or you could say that
unsafePerformIO does allow such things, and that's why it's not type-
safe).
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] Re: Do I need to roll my own?

2010-03-31 Thread John Lato
Hi Dave,

 From: David Leimbach leim...@gmail.com

 I'm looking at iteratee as a way to replace my erroneous and really
 inefficient lazy-IO-based backend for an expect like Monad DSL I've been
 working for about 6 months or so now on and off.

 The problem is I want something like:

 expect some String
 send some response

 to block or perhaps timeout, depending on the environment, looking for some
 String on an input Handle, and it appears that iteratee works in a very
 fixed block size.  While a fixed block size is ok, if I can put back unused
 bytes into the enumerator somehow (I may need to put a LOT back in some
 cases, but in the common case I will not need to put any back as most
 expect-like scripts typically catch the last few bytes of data sent before
 the peer is blocked waiting for a response...)

I'm quite sure I don't know what you're trying to do.  The only time I
can think of needing this is if you're running an iteratee on a file
handle, keeping the handle open, then running another iteratee on it.
Is this what you're doing?  If so, I would make a new run function:

runResidue :: (Monad m, SC.StreamChunk s el) = IterateeG s el m a - m (a, s)
runResidue iter = runIter iter (EOF Nothing) = \res -
  case res of
Done x s - return (x, s)
Cont _ e - error $ control message:  ++ show e

This function will return the unused portion of the stream, then you
can do this:

enumResidue :: Handle - s - EnumeratorGM s el m a
enumResidue h s = enumPure1Chunk s . enumHandle h

Is this what you need?  If I'm completely wrong about what you're
trying to do (or you're using multiple threads), there are other
options.

You also may want to look at iteratee-HEAD.  The implementation has
been cleaned up a lot, the block sizes are user-specified, and there's
an exception-based, user-extensible mechanism for iteratees to alter
enumerator behavior.

Sincerely,
John
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] Re: Do I need to roll my own?

2010-03-31 Thread David Leimbach
On Wed, Mar 31, 2010 at 2:12 PM, John Lato jwl...@gmail.com wrote:

 Hi Dave,

  From: David Leimbach leim...@gmail.com
 
  I'm looking at iteratee as a way to replace my erroneous and really
  inefficient lazy-IO-based backend for an expect like Monad DSL I've been
  working for about 6 months or so now on and off.
 
  The problem is I want something like:
 
  expect some String
  send some response
 
  to block or perhaps timeout, depending on the environment, looking for
 some
  String on an input Handle, and it appears that iteratee works in a very
  fixed block size.  While a fixed block size is ok, if I can put back
 unused
  bytes into the enumerator somehow (I may need to put a LOT back in some
  cases, but in the common case I will not need to put any back as most
  expect-like scripts typically catch the last few bytes of data sent
 before
  the peer is blocked waiting for a response...)

 I'm quite sure I don't know what you're trying to do.  The only time I
 can think of needing this is if you're running an iteratee on a file
 handle, keeping the handle open, then running another iteratee on it.
 Is this what you're doing?  If so, I would make a new run function:

 runResidue :: (Monad m, SC.StreamChunk s el) = IterateeG s el m a - m (a,
 s)
 runResidue iter = runIter iter (EOF Nothing) = \res -
  case res of
Done x s - return (x, s)
Cont _ e - error $ control message:  ++ show e

 This function will return the unused portion of the stream, then you
 can do this:

 enumResidue :: Handle - s - EnumeratorGM s el m a
 enumResidue h s = enumPure1Chunk s . enumHandle h

 Is this what you need?  If I'm completely wrong about what you're
 trying to do (or you're using multiple threads), there are other
 options.


The problem is I am not sure what it was I needed to get started to begin
with.  For a moment it seemed that I could be throwing out data that's been
read, but not yet fed to an iteratee step.  If that's not the case, I'll
never need to put back any characters. The attoparsec-iteratee example
posted, plus some experimentation has led me to believe I don't need to
worry about this sort of thing for the kind of processing I'm looking to do.



 You also may want to look at iteratee-HEAD.  The implementation has
 been cleaned up a lot, the block sizes are user-specified, and there's
 an exception-based, user-extensible mechanism for iteratees to alter
 enumerator behavior.


That's very compelling.

Here's the properties of the system I'm trying to build (in fact I've built
this system with Haskell already months ago, but trying to evaluate if
iteratee can fix problems I've got now)

1. Must have an expect-like language to a subprocess over a pair of Handles
such that I can query what is normally a command line interface as a polling
refresher thread to a cache.  Note that there may be many sub-processes with
a poller/cache (up to 6 so far).  Data produced is dumped as records to
stdout from each thread such that the process that spawned this haskell
program can parse those records and update it's view of this particular part
of the world.

2. Must be able to interleave commands between polled record data from the
processes in 1.  These commands come in over this process's stdin from the
program that started the Haskell program.

3. The polling process in 1, must be able to respond to a timeout situation.
 In this system, a cable could become disconnected or a part of the system
could become unavailable, or a part of the system underneath could become
unreliable and require a restart to guarantee the serviceability of the
whole system.

I have 1 and 2 working fine in a current iteration of the system, but
because we're dealing with a pretty complex stack, 3 is really necessary
too, and I've conquered my timeout issues from earlier in a reasonable
enough way.  The problem is that the timeout handler apparently runs into
problems that I think stem from lazyIO not having been evaluated on a handle
yet, but the timeout handler has invalidated that handle, and then that
thunk, which was partially applied, is now talking to some broken value.

As far as I know, I can't go back and prevent previously bound thunks that
have the wrong handle from executing, if that is truly what's happening.
 What I'd like to do is prevent that situation from ever happening to begin
with, or at least rule it out.

I'm hoping version 2 of this system to be based on iteratee and avoid this
sort of problem at all.

The alternative is to write this in another language, but that throws out a
lot of nice and simple code that's present in the non IO bits of this code,
for dealing with parsing and data serialization.

Dave


 Sincerely,
 John

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] Re: do we need types?

2010-02-26 Thread Johannes Waldmann
A type is, well, a type.
A type class is a relation between types.

The confusion probably comes from OO programming 
where (interfaces) describe unary relations (= one parameter type classes).

(begin rant) I wouldn't easily give up algebraic data types 
just because OO programmers don't seem know about them -
so the re-invent them and call it composite pattern...



___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] Re: do we need types?

2010-02-26 Thread Maurí­cio CA

A type class is a relation between types.


Yes, but not officially, just de facto:

http://hackage.haskell.org/trac/haskell-prime/ticket/90

Best,

Maurício

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] Re: do we need types?

2010-02-26 Thread Pasqualino Titto Assini
This seems quite relevant:

http://lambda-the-ultimate.org/node/3837

 titto
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Re: do we need types?

2010-02-26 Thread Daniel Fischer
Am Freitag 26 Februar 2010 14:07:07 schrieb Johannes Waldmann:
 I wouldn't easily give up algebraic data types

Nor I. Without easily defined ADTs, Haskell wouldn't be nearly so awesome.
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] Re: Do you need Windows USB in Haskell?

2009-12-07 Thread Maurí­cio CA

 I don't need usb and I can't say I'm a windows user, but I'd
 be glad to test it since I have it on a virtual machine. In my
 case, installation fails on bindings-common.

bindings-common fails on windows due to an old version of C
library with GHC's windows version of gcc. Current version of
bindings-libusb uses bindings-DSL.

I'm glad that you offered to help. But usb is not supposed to
work on windows yet. The windows version of the C library has
been worked on recently, so, I would need someone who would
follow closely this still alpha code and maybe even sugesting
adaptations to libusb-1.x build system if necessary. I don't
think it's fair to expect that from someone who isn't going to use
the library.

Thanks! Best,
Maurício

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] Re: do nmergeIO or mergeIO preserve order?

2009-03-11 Thread ChrisK

Anatoly Yakovenko wrote:

do nmergeIO or mergeIO preserve order? or not preserve order?


If you have a list of operations [IO a] then the future package at

http://hackage.haskell.org/cgi-bin/hackage-scripts/package/future

can do this.  It's 'forkPromises' function returns a Chan a which can be used 
to get the non-order preserving results (actually Either SomeExcption a).  If 
you are feeling lucky you can use getChanContents and filter to get a lazy 
[a] which is the results as they are completed.


--
Chris

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Re: Do real programs need IO? (was IO is a bad example for Monads)

2007-12-10 Thread Daniel Fischer
Am Montag, 10. Dezember 2007 07:05 schrieb Maurí­cio:
(...)
 Would you deny that any useful programme has to do at least some of
  
   the following:
 -accept programme arguments at invocation
 -get input, be it from a keyboard, mouse, reading files, pipes...
 -output a result or state info, to the monitor, a file, a pipe...
  
  ===

 As long as we use current interfaces, no one
 would deny it. 

I thought Conal did, but it turned out that he just had a wider concept of RTS 
than I.

But after reading some stuff
 about Epigram language, I wonder if those
 ideas could not be used to write a better
 interface to computers. Then, all those tasks
 would be handled by your interface plug-ins,
 not by programs.

 Really, we need to do all of that today. But
 I believe reading from keyboard, files
 etc. should not be part of programs we write
 daily, just a task for a basic interface to
 which our programs should be linked.

Agreed, but until then, we need IO to write 'real' programmes. We can already 
encapsulate it somewhat using libs like TV, as I learnt yesterday, but even 
more encapsulation wouldn't be bad.

 Best,
 Maurício

Cheers,
Daniel

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] Re: Do real programs need IO? (was IO is a bad example for Monads)

2007-12-09 Thread Maurí­cio

  (...)
   Would you deny that any useful programme has to do at least some of
 the following:
   -accept programme arguments at invocation
   -get input, be it from a keyboard, mouse, reading files, pipes...
   -output a result or state info, to the monitor, a file, a pipe...
===


As long as we use current interfaces, no one
would deny it. But after reading some stuff
about Epigram language, I wonder if those
ideas could not be used to write a better
interface to computers. Then, all those tasks
would be handled by your interface plug-ins,
not by programs.

Really, we need to do all of that today. But
I believe reading from keyboard, files
etc. should not be part of programs we write
daily, just a task for a basic interface to
which our programs should be linked.

Best,
Maurício

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Re: do

2007-12-04 Thread Luke Palmer
On Dec 4, 2007 11:39 AM, Jules Bean [EMAIL PROTECTED] wrote:
 Ben Franksen wrote:
  I don't buy this. As has been noted by others before, IO is a very special
  case, in that it can't be defined in Haskell itself, and there is no
  evaluation function runIO :: IO a - a.

 This is a straw man. Most monads will not have such a function:

When I first learned monads, I heard that once you get into IO, you
can never get out.
The point here was that that doesn't generalize, so a student might
start thinking that
a monad is like a taint flag or something.  Not to say that statement
that it's a complete
falsity when generalized to other monads -- it's reflective of the
algebra of monads --
you just have to define never a little differently. :-)

In any case, I don't think that's a big issue.  While it is important
to eliminate things
that monads aren't from students' possible models, it's better just to
build a good model
in the first place.

FWIW, the list monad was how I made the leap from monads do IO to
monads do nifty stuff.

Luke

 There is no function (State s a) - a.

 There is no function (r - a) - a.

 There is no function (Random a) - a. [assuming some random monad, often
 discussed]

 There is no function (Supply s a) - a. [Another useful monad although
 not one of the standard ones]

 There are no (total) functions Maybe a - a, [a] - a, Either e a - a.



 As to the topic of the thread: I agree IO is an unusual monad. I'm not
 sure if I agree that it shouldn't be used as a teaching basis. I think
 there are all kinds of ways to teach haskell; I'd be inclined to want to
 start with some IO, without explaining the plumbing in detail, and then
 come back to it later with better perspective when discussing general
 monads.

 Jules

 ___
 Haskell-Cafe mailing list
 Haskell-Cafe@haskell.org
 http://www.haskell.org/mailman/listinfo/haskell-cafe

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Re: do

2007-12-04 Thread Jules Bean

Ben Franksen wrote:

I don't buy this. As has been noted by others before, IO is a very special
case, in that it can't be defined in Haskell itself, and there is no
evaluation function runIO :: IO a - a.


This is a straw man. Most monads will not have such a function:

There is no function (State s a) - a.

There is no function (r - a) - a.

There is no function (Random a) - a. [assuming some random monad, often 
discussed]


There is no function (Supply s a) - a. [Another useful monad although 
not one of the standard ones]


There are no (total) functions Maybe a - a, [a] - a, Either e a - a.



As to the topic of the thread: I agree IO is an unusual monad. I'm not 
sure if I agree that it shouldn't be used as a teaching basis. I think 
there are all kinds of ways to teach haskell; I'd be inclined to want to 
start with some IO, without explaining the plumbing in detail, and then 
come back to it later with better perspective when discussing general 
monads.


Jules
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] Re: do

2007-12-03 Thread Ben Franksen
Dan Piponi wrote:
 On Dec 3, 2007 1:09 PM, Denis Bueno [EMAIL PROTECTED] wrote:
 
 I don't think I can conclude that there are *no* reasons to teach the
 do-notation first.  I just think that it is more instructive to teach
 it later.
 
 It's standard in mathematics teaching, when introducing a mathematical
 structure X, to ensure that students have the knowledge to understand
 an example of X before they see the definition of X. So students won't
 study groups before they've met the integers, they won't study fields
 before they've met the rationals, and they won't study topology until
 they're familiar with the real line. Not just met them either, usually
 they've usually completely internalised the examples before moving
 onto the general structure.

Right.

 The problem with monads is that students have never knowingly met an
 example of a monad before.

When one learns about Groups one hasn't met them /knowingly/ before, either.
It may be that one has learned the laws that govern arithmetic; but it is
not at all clear why one would want to look at one of the operations in
separation, i.e. what the generality of the concept might be good for. This
becomes clear only after having seen examples of a group whose elements
are /not/ integers.

 If you teach them do-notation for IO 
 without monads, and they get completely familiar with it (which (1) I
 claim is easy:

http://sigfpe.blogspot.com/2007/11/io-monad-for-people-who-simply-dont.html
 and (2) is inevitable if they want to see the output of their programs)
 then when they come to learning about monads in general they'll have an
 example they don't even have to think about. 

I don't buy this. As has been noted by others before, IO is a very special
case, in that it can't be defined in Haskell itself, and there is no
evaluation function runIO :: IO a - a.

I'd rather use a simple example like Maybe (modeling failure as an effect).
It can be completely understood even as a beginner, and is non-trivial
enough to demonstrate the utility of the concept 'monad'.

Cheers
Ben

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Re: do

2007-12-03 Thread Dan Piponi
On Dec 3, 2007 3:54 PM, Ben Franksen [EMAIL PROTECTED] wrote:

 I don't buy this. As has been noted by others before, IO is a very special
 case, in that it can't be defined in Haskell itself, and there is no
 evaluation function runIO :: IO a - a.

I'm not sure what a function of type m a - a has to do with the
concept of a monad. And I don't really see what the problem is with
the IO monad not being definable in (pure) Haskell. IO exposes the
same interface as every other Monad, and you need to use that
interface to get visible results. So people have to learn it whatever.
And the whole point of the Monad is that it's an interface, not a
specific implementation.

 I'd rather use a simple example like Maybe (modeling failure as an effect).

And I'd like to see more people getting off the ground doing
interesting stuff with Haskell before their attention spans for
pointless-seeming new stuff run out. I'm not talking about the
smartest people in computer science courses here. I'm talking about
the millions of people writing everyday Python and Ruby scripts, say,
who might benefit from a more expressive, type-safe, well-thought out,
fast and compiled language.
--
Dan
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Fw: [Haskell-cafe] Re: do

2007-12-03 Thread Thomas Hartman
It took me forever to get comfortable with monads.

I think it helps if you've seen continuations, or done FP before, or a 
variety of things that build familiarity.

But probably the only thing that I think will work for the masses of 
plodders (there are always a few stars to crash the curve) is a desire to 
learn and tons of practice.

I wouldn't worry so much about the ideal way to introduce the material.

Oh, one other thing. You learn monads when you need them. You need IO 
right away... well, after you tired of playing with pure functions in the 
ghci sandbox.

my 2c.

t.






Dan Piponi [EMAIL PROTECTED] 
Sent by: [EMAIL PROTECTED]
12/03/2007 07:19 PM

To
haskell-cafe@haskell.org
cc

Subject
Re: [Haskell-cafe] Re: do






On Dec 3, 2007 3:54 PM, Ben Franksen [EMAIL PROTECTED] wrote:

 I don't buy this. As has been noted by others before, IO is a very 
special
 case, in that it can't be defined in Haskell itself, and there is no
 evaluation function runIO :: IO a - a.

I'm not sure what a function of type m a - a has to do with the
concept of a monad. And I don't really see what the problem is with
the IO monad not being definable in (pure) Haskell. IO exposes the
same interface as every other Monad, and you need to use that
interface to get visible results. So people have to learn it whatever.
And the whole point of the Monad is that it's an interface, not a
specific implementation.

 I'd rather use a simple example like Maybe (modeling failure as an 
effect).

And I'd like to see more people getting off the ground doing
interesting stuff with Haskell before their attention spans for
pointless-seeming new stuff run out. I'm not talking about the
smartest people in computer science courses here. I'm talking about
the millions of people writing everyday Python and Ruby scripts, say,
who might benefit from a more expressive, type-safe, well-thought out,
fast and compiled language.
--
Dan
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe



---

This e-mail may contain confidential and/or privileged information. If you 
are not the intended recipient (or have received this e-mail in error) 
please notify the sender immediately and destroy this e-mail. Any 
unauthorized copying, disclosure or distribution of the material in this 
e-mail is strictly forbidden.___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Re: do

2007-12-03 Thread Jonathan Cast

On 3 Dec 2007, at 4:19 PM, Dan Piponi wrote:


On Dec 3, 2007 3:54 PM, Ben Franksen [EMAIL PROTECTED] wrote:

I don't buy this. As has been noted by others before, IO is a very  
special

case, in that it can't be defined in Haskell itself, and there is no
evaluation function runIO :: IO a - a.


I'm not sure what a function of type m a - a has to do with the
concept of a monad.


Nothing.  But there are plenty of legal, safe functions of type m a - 
 a for almost all monads m.  Except those based on IO.


So leading off with IO can lead to the impression that (a) monads are  
impossible to break out of / can't be used in purely functional code  
or (b) the main point of monads is to let you write imperative code  
in Haskell.  The main point of monads is that they're so common in  
Haskell we'd be crazy not to call them /something/, just so we have  
something to say when we realize, hey, this is another of those  
thingies with a return and a bind!  IO is quite atypical as far as  
the class of monads we use every day in Haskell goes; the absence of  
any useful, safe, pure function of type IO a - a is a (small)  
instance of that atypicality.


IMHO, teaching IO first and then saying, monads are things that are  
like IO, is very counter-productive.  In particular, I think it's why  
so few people understand the list monad (which is of course one of  
the pardigmatic examples).


Just my 2c, of course.

jcc

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] Re: do/if/then/else confusion

2007-11-01 Thread David Carter

David Carter wrote:

Another newbie question, but I can't seem to find any answers on the 
web...



Just figured it out myself ... I need a do after the else, of 
course. (But I still think the error message is less than helpful!).


Sorry for the bandwidth

David



Can someone tell me what's wrong with this?

import qualified System.Posix.Directory as PD

readdirAll :: PD.DirStream - IO [String]
readdirAll d =
  do dir - PD.readDirStream d
 if dir == 
   then return []
   else rest - readdirAll d
return (dir:rest)

Compiling with GHC 6.6.1 gives me the not-very-useful message Parse 
error in pattern, pointing to the i of if. I've tried all kinds 
of alternative indentations (including indenting the else more), 
bracketings etc, but nothing helps.


Thanks

David






--
The Wellcome Trust Sanger Institute is operated by Genome Research 
Limited, a charity registered in England with number 1021457 and a 
company registered in England with number 2742969, whose registered 
office is 215 Euston Road, London, NW1 2BE. 
___

Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Re: do/if/then/else confusion

2007-11-01 Thread Felipe Lessa
On 11/1/07, David Carter [EMAIL PROTECTED] wrote:
 (But I still think the error message is less than helpful!).

Maybe a bug should be filled?

-- 
Felipe.
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] Re: do/if/then/else confusion

2007-11-01 Thread Maurí­cio

 (...)
 Can someone tell me what's wrong with this?
 import qualified System.Posix.Directory as PD

 readdirAll :: PD.DirStream - IO [String]
 readdirAll d =
   do dir - PD.readDirStream d
  if dir == 
then return []
else rest - readdirAll d
 return (dir:rest)
 (...)

I don't know if this helps or disturbs, but I
wrote a few different versions of your code
as an exercise. If you want to try it, just
uncomment the versions you want to check. The
complete program below lists all files in
current directory, using 'readdirAll' to get
the full list.

Best,
Maurício


module Main (Main.main) where
import qualified System.Posix.Directory as PD
import Data.List
import Control.Monad

main :: IO ()

readdirAll :: PD.DirStream - IO [String]
readdirAll ds = liftM reverse $ read []
  where
read (:t) = return t
read list = (PD.readDirStream ds) = glue
  where glue f = read (f:list)
{-
readdirAll ds = read
  where
read = (PD.readDirStream ds) = rest
rest  = return []
rest h = liftM (h:) read
-}
{-
readdirAll ds = do
f - PD.readDirStream ds
rest f
  where
rest  = return []
rest h = return (h:) `ap` (readdirAll ds)
-}
main = (PD.openDirStream .) =
 readdirAll = (putStrLn.show)

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] Re: do

2007-10-15 Thread ChrisK
[EMAIL PROTECTED] wrote:
 Peter Verswyvelen writes about non-monadic IO, unique external worlds:
 But... isn't this what the Haskell compiler  runtime do internally
 when IO monads are executed? Passing the RealWorld singleton from
 action to action? 

In GHC, yes.

 
 I never looked into any Haskell compiler. Chalmers, or York, don't
 remember,
 used continuations, this seems a bit different from the Clean approach, but
 I don't really know the gory details.
 To me, no real difference exists between IO monads and Clean's uniques
 types; it's just a different approach to tackle the same problem. 
 
 Yes, *different approach*. So, there *are* differences. Compilers, anyway,
 are special applications. I wanted to see - responding to Brandon - a
 normal Haskell program, which does IO without monads, that't all.

 The problem is then when you hide something, you hide. It is possible to
 superpose a kind of monadic framework on unique worlds, files, etc. in
 Clean, but the reverse operation goes beyond my horizons.

 Some examples, anybody?
 Jerzy Karczmarczuk

I don't have examples, but I can show you where the gory details are hiding:

The Haskell 98 standard specifies the API for input/output to be using the IO
monad.  If you want to use Haskell 98 to do input/output without the IO monad
then you will find that you cannot do so. I see three ways to go around 
Haskell98.

Common caveat: The thing that using the provided IO monad does is provide a
standard way of sequencing two input/output operations.   Once you avoid that
sequencing then you indeterminism unless you provide your own sequencing 
manually.

The first, which you may decide does not really count, is using
unsafePerformIO or unsafeInterleaveIO and avoiding the sequencing provided
by the IO monad.  This still does nothing to tell you about the gory details.

As a cheat: If you use the FFI addendum then you can access all the impure c
input/output functions and lie about their type so that are not in IO.  Then you
could manually manage their sequencing and control everything.  This comes
closer to understanding how the standard IO operations are implemented in the
gory details.

For the GHC implementation of Haskell it is possible to go inside the IO monad
and operate using the same gory details that GHC uses.  This is probably what
you want to see, but note that it is not the only compiler or the only way to do
this.

The details are in the source at
http://darcs.haskell.org/ghc-6.6/packages/base/GHC/
in IOBase.lhs and IO.hs and so on...

From IOBase.lhs I see that GHC uses a newtype around a function of type
State b - (State b, a) to represent IO a.
The State b is actually an unboxed type State# RealWorld.  The tuple is
likewise an unboxed (# , #) tuple.

 newtype IO a = IO (State# RealWorld - (# State# RealWorld, a #))
 
 unIO :: IO a - (State# RealWorld - (# State# RealWorld, a #))
 unIO (IO a) = a

Also in IOBase.lhs this is made into a Functor and, inevitably, a monad:

 instance  Functor IO where
fmap f x = x = (return . f)
 
 instance  Monad IO  where
 {-# INLINE return #-}
 {-# INLINE ()   #-}
 {-# INLINE (=)  #-}
 m  k  =  m = \ _ - k
 return x  = returnIO x
 
 m = k = bindIO m k
 fail s= failIO s

 returnIO :: a - IO a
 returnIO x = IO (\ s - (# s, x #))

 bindIO :: IO a - (a - IO b) - IO b
 bindIO (IO m) k = IO ( \ s -
   case m s of 
 (# new_s, a #) - unIO (k a) new_s
   )

 failIO :: String - IO a
 failIO s = ioError (userError s)

 -- | Raise an 'IOError' in the 'IO' monad.
 ioError :: IOError - IO a 
 ioError   =  ioException

 ioException   :: IOException - IO a
 ioException err =  IO $ raiseIO# (IOException err)
 

Where raiseIO# is from GHC.Prim
http://www.haskell.org/ghc/docs/latest/html/libraries/base/GHC-Prim.html
http://darcs.haskell.org/ghc/compiler/prelude/primops.txt.pp

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] Re: do

2007-10-15 Thread ChrisK
Brandon S. Allbery KF8NH wrote:
 
 On Oct 15, 2007, at 13:32 , Peter Verswyvelen wrote:
 
 [EMAIL PROTECTED] wrote:
 Yes, *different approach*. So, there *are* differences. Compilers,
 anyway,
 are special applications. I wanted to see - responding to Brandon - a
 normal Haskell program, which does IO without monads, that't all.
 The problem is then when you hide something, you hide. It is
 possible to
 superpose a kind of monadic framework on unique worlds, files, etc. in
 Clean, but the reverse operation goes beyond my horizons.
 Some examples, anybody?
 Ah yes, I see what you mean now. I have no idea, I guess only
 unsafePerformIO will allow you to do something like that... But that
 will completely break referential transparency. But I really don't
 know. What do the experts have to say?
 
 Use the source of unsafePerformIO as an example of how to write code
 which passes around RealWorld explicitly, but without unencapsulating it
 like unsafePerformIO does.
 
 The main problem here, I think, is that because all the GHC runtime's
 functions that interact with RealWorld (aside from unsafe*IO) are
 themselves only exported wrapped up in IO, you can't (as far as I know)
 get at the lower level internal (e.g.) putStrLn' :: RealWorld - String
 - (# RealWorld,() #) to do I/O in a direct/explicit/non-monadic style. 
 In theory, one could export those and use them directly.

Well, if you import GHC.IOBase then you get


 newtype IO a = IO (State# RealWorld - (# State# RealWorld, a #))

 unIO :: IO a - (State# RealWorld - (# State# RealWorld, a #))
 unIO (IO a) = a

Then the type of putStrLn:

-- putStrLn :: String - IO ()

means that putStrLn' can be defined as

putStrLn' :: String - State# RealWorld - (# State# RealWorld, a #)
putStrLn' = unIO . putStrLn

Now you have the unboxed tuple and need to work with many 'case' statements to
accomplish anything.

Also you need to get you hand on State# RealWorld either
  (1) Honestly, by wrapping your code in IO again and using it normally
  (2) From a copy, via unsafeInterleaveIO
  (3) From nowhere, via unsafePerformIO





 
 (Actually, as a practical matter, IIRC GHC knows about RealWorld and
 removes all of it when generating cmm code once it's done the job of
 sequencing Haskell evaluation; I'm not sure how well that would work if
 you wrote I/O in direct/explicit style.  unsafePerformIO doesn't really
 count for that because it removes the RealWorld itself.)
 

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Re: do

2007-10-15 Thread Brandon S. Allbery KF8NH


On Oct 15, 2007, at 19:00 , ChrisK wrote:


Brandon S. Allbery KF8NH wrote:

Use the source of unsafePerformIO as an example of how to write code
which passes around RealWorld explicitly, but without  
unencapsulating it

like unsafePerformIO does.

The main problem here, I think, is that because all the GHC runtime's
functions that interact with RealWorld (aside from unsafe*IO) are
themselves only exported wrapped up in IO, you can't (as far as I  
know)
get at the lower level internal (e.g.) putStrLn' :: RealWorld -  
String
- (# RealWorld,() #) to do I/O in a direct/explicit/non-monadic  
style.

In theory, one could export those and use them directly.


Well, if you import GHC.IOBase then you get


newtype IO a = IO (State# RealWorld - (# State# RealWorld, a #))

unIO :: IO a - (State# RealWorld - (# State# RealWorld, a #))
unIO (IO a) = a


Then the type of putStrLn:

-- putStrLn :: String - IO ()

means that putStrLn' can be defined as

putStrLn' :: String - State# RealWorld - (# State# RealWorld, a #)
putStrLn' = unIO . putStrLn

Now you have the unboxed tuple and need to work with many 'case'  
statements to

accomplish anything.

Also you need to get you hand on State# RealWorld either
  (1) Honestly, by wrapping your code in IO again and using it  
normally

  (2) From a copy, via unsafeInterleaveIO
  (3) From nowhere, via unsafePerformIO


(4) Honestly but unwrapped, by defining main in the same desugared  
way (takes State# RealWorld and returns (# State# RealWorld,a #) (or  
(# State# RealWorld,() #) if you stick to the H98 definition of  
main's type), allowing the runtime to pass it in and otherwise not  
doing anything other than propagating it.


My real problem was that I incorrectly recalled IO's type to be based  
on ST, not State (i.e. had a forall to prevent anything from being  
able to do anything to/with the State# RealWorld other than pass it  
on unchanged without triggering a type error).  I should have  
realized that was wrong because unsafePerformIO is itself expressible  
in Haskell (-fglasgow-exts is needed to make # an identifier  
character and to enable unboxed types and unboxed tuples, but does  
not make it possible to cross an existential type barrier).


--
brandon s. allbery [solaris,freebsd,perl,pugs,haskell] [EMAIL PROTECTED]
system administrator [openafs,heimdal,too many hats] [EMAIL PROTECTED]
electrical and computer engineering, carnegie mellon universityKF8NH


___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Re: do

2007-10-15 Thread Ryan Ingram
On 10/15/07, ChrisK [EMAIL PROTECTED] wrote:
 Also you need to get you hand on State# RealWorld either
  (1) Honestly, by wrapping your code in IO again and using it normally
  (2) From a copy, via unsafeInterleaveIO
  (3) From nowhere, via unsafePerformIO

Or you can get it honestly via lifting:

liftRawIO :: (State# RealWorld - (# State# RealWorld, a #)) - IO a
liftRawIO = GHC.IOBase.IO

main = liftRawIO rawMain

rawMain :: State# RealWorld- (# State# RealWorld, () #)
{- implement rawMain here -}

  -- ryan
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Re: do

2007-10-15 Thread Ryan Ingram
Oops, I read too fast, you mentioned that as #1.

On 10/15/07, ChrisK [EMAIL PROTECTED] wrote:
 Also you need to get you hand on State# RealWorld either
  (1) Honestly, by wrapping your code in IO again and using it normally

Silly me.

  -- ryan
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Re: do

2007-10-15 Thread Brandon S. Allbery KF8NH
I actually got this done several hours ago, but my DSL is being  
annoying tonight...


Anyway, here's a simple example of how to do explicit/non-monadic I/O  
in GHC.  (It *only* works in GHC; other compilers have different  
internal implementations of IO.)  I specifically modeled it to  
highlight its resemblance to State.


{-# OPTIONS_GHC -fno-implicit-prelude -fglasgow-exts #-}

import GHC.Base
import GHC.IOBase
import GHC.IO
import GHC.Handle (stdout)

{-
  This is horrible evil to demonstrate how to do I/O without the  
help of

  the IO monad.  And yes, it is very much a help.

  The trick here is that the type IO is a state-like type:  a value
  constructor which wraps a function.  Thus, working with it manually
  requires that we have a runIO.(*)  Naively, this looks like  
unsafePerformIO;
  but in fact it is not, as unsafePerformIO uses the magic builtin  
RealWorld#
  to create a new State# RealWorld on the fly, but in fact we are  
passing on
  the one we get from somewhere else (ultimately, the initial state  
for main).

  (Additionally, we don't unwrap the resulting tuple; we return it.)
  This is why runIO is really *safePerformIO* (i.e. entirely normal  
I/O).


  (*) Well, not absolutely.  GHC.IOBase uses unIO instead:
unIO (IO f) = f
  I think this is a little cleaner, and better demonstrates how  
IO is
  really not all that special, but simply a way to pass state  
around.

-}

-- treat IO like State, for demonstration purposes
runIO  :: IO a - State# RealWorld - (# State# RealWorld,a #)
runIO (IO f) s =  f s

-- And here's our simple hello, world demo program
main :: IO ()
main =  IO (\s - runIO (putStrLn' hello, world) s)

-- this is just to demonstrate how to compose I/O actions.  we could  
just

-- call the real putStrLn above instead; it is operationally identical.

-- write a string followed by newline to stdout
-- this is completely normal!
putStrLn' :: String - IO ()
putStrLn' =  hPutStrLn' stdout

-- write a string followed by newline to a Handle
hPutStrLn'   :: Handle - String - IO ()
hPutStrLn' h str =  IO (\s - let (# s',_ #) = runIO (hPutStr' h str) s
   in runIO (hPutChar h '\n') s')

-- write a string, iteratively, to a Handle
hPutStr'  :: Handle - String - IO ()
hPutStr' _ [] =  IO (\s - (# s,() #))
hPutStr' h (c:cs) =  IO (\s - let (# s',_ #) = runIO (hPutChar h c) s
in runIO (hPutStr' h cs) s')


--
brandon s. allbery [solaris,freebsd,perl,pugs,haskell] [EMAIL PROTECTED]
system administrator [openafs,heimdal,too many hats] [EMAIL PROTECTED]
electrical and computer engineering, carnegie mellon universityKF8NH


___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe