Send Beginners mailing list submissions to
        beginners@haskell.org

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
        beginners-requ...@haskell.org

You can reach the person managing the list at
        beginners-ow...@haskell.org

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


Today's Topics:

   1. Re:  Explicit specification of function types (Peter Verswyvelen)
   2. Re:  Explicit specification of function types (Zachary Turner)
   3.  Tutorial/Book with Exercises (Zachary Turner)
   4.  Event handling in GTK2hs: managing events and    global state
      (?????????? ?. ????????)
   5. Re:  Event handling in GTK2hs: managing events and        global
      state (Brandon S. Allbery KF8NH)


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

Message: 1
Date: Wed, 25 Mar 2009 00:02:55 +0100
From: Peter Verswyvelen <bugf...@gmail.com>
Subject: Re: [Haskell-beginners] Explicit specification of function
        types
To: "Brandon S. Allbery KF8NH" <allb...@ece.cmu.edu>
Cc: beginners@haskell.org
Message-ID:
        <a88790d10903241602v53ace185rdbfde185931a9...@mail.gmail.com>
Content-Type: text/plain; charset="iso-8859-1"

2009/3/24 Brandon S. Allbery KF8NH <allb...@ece.cmu.edu>

> That's my understanding, F++ types don't require any runtime lookups so
> inference can't surprise you.
>

It uses .NET interfaces for that, but the F# expert book mentions they would
like to have type classes in a future version of the language.


> in Haskell can do unexpected things:  F++ has parenthesized function
> arguments, so it will catch too few/too many arguments directly, but
> Haskell's uncurried function call notation almost guarantees strange errors
> in those cases even if you have everything explicitly typed.
>

Not really, F# has both curried and uncurried forms, just like Haskell.

It is true that F# encourages automatic generalization without type
signatures. You never need to give one, even for exported modules.

But the lack of type classes has its price. E.g.

add x y = x + y

What is the type of add in F#?

Well, that depends on the first usage of this function... Give it Ints and
it becomes add :: Int -> Int -> Int, and you can't use it on Doubles any
more. Very confusing, since you can use the overloaded (+) on any type.
These are current limitations of the language.

At least that what I understood from it...
-------------- next part --------------
An HTML attachment was scrubbed...
URL: 
http://www.haskell.org/pipermail/beginners/attachments/20090325/10266608/attachment-0001.htm

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

Message: 2
Date: Tue, 24 Mar 2009 19:51:06 -0500
From: Zachary Turner <divisorthe...@gmail.com>
Subject: Re: [Haskell-beginners] Explicit specification of function
        types
To: Peter Verswyvelen <bugf...@gmail.com>
Cc: beginners@haskell.org
Message-ID:
        <478231340903241751g6ecc795dm9456555b6690c...@mail.gmail.com>
Content-Type: text/plain; charset="iso-8859-1"

On Tue, Mar 24, 2009 at 6:02 PM, Peter Verswyvelen <bugf...@gmail.com>wrote:

>
>
> 2009/3/24 Brandon S. Allbery KF8NH <allb...@ece.cmu.edu>
>
>> That's my understanding, F++ types don't require any runtime lookups so
>> inference can't surprise you.
>>
>
> It uses .NET interfaces for that, but the F# expert book mentions they
> would like to have type classes in a future version of the language.
>
>
>> in Haskell can do unexpected things:  F++ has parenthesized function
>> arguments, so it will catch too few/too many arguments directly, but
>> Haskell's uncurried function call notation almost guarantees strange errors
>> in those cases even if you have everything explicitly typed.
>>
>
> Not really, F# has both curried and uncurried forms, just like Haskell.
>
> It is true that F# encourages automatic generalization without type
> signatures. You never need to give one, even for exported modules.
>
> But the lack of type classes has its price. E.g.
>
> add x y = x + y
>
> What is the type of add in F#?
>
> Well, that depends on the first usage of this function... Give it Ints and
> it becomes add :: Int -> Int -> Int, and you can't use it on Doubles any
> more. Very confusing, since you can use the overloaded (+) on any type.
> These are current limitations of the language.
>
> At least that what I understood from it...
>
>
What you say is partially true.  For example, if delcared as you typed it, a
rule similar to the monomorphism restriction (from what I understand of the
monomorphism restriction) applies.  If it's never used, x and y are of type
int, and if they are used, x and y pick up the type of whatever you call it
with.  So doubles if you invoke it with 3.0 and 4.0, ints if you invoke it
with 3 and 4, and an error if you invoke it once with doulbes and once with
ints.

The F# answer to this is to "inline" the function.  For example:

let inline add (x:'a) (y:'a) : 'a = x+y

let result1 = add 3 4
let result2 = add 3.0 4.0

Hover over this declaration of add to get its type and you see "add : 'a ->
'a -> 'a (requires member (+))

Here, result1 is an int and result2 is a double.  I haven't heard this from
straight from the developers, but I suspect inlining is necessary due to the
.NET Framework's support for reflection.  Consider, for example, what would
happen if you tried to obtain the method add via reflection and there was
code for exactly 1 add method present in the binary.  The code would have no
reasonable way to behave.  By inlining, I believe it inserts multiple
definitions of hte function into the code, similar to what you get when you
instantiate a C++ template.

Anyway, a bit off topic, but at the very least I'm starting to understand
why it's ok in F# but not really so much in Haskell.  The issue of
documenting the function I think is kind of a non issue actually, because if
it were really just for the purposes of documentation you could just comment
out the the type signature so that it's still visible but not interpreted by
the compiler.  In F# though the documentation is even less of an issue since
you get automatic mouse-hover type definitions.  The same thing applies to
the issue of detecting type errors.  It's pretty easy to find them when all
the type inference mismatches are underlined for you on the fly.  But in
Haskell it seems the problem of finding type errors is made more difficult
not only by the lack of a helpful syntax underliner, but also by the
typeclasses, which make the errors even more far removed from what you would
expect.  Not to mention the performance penalties associated with making
something too generic, which I didn't think of originally.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: 
http://www.haskell.org/pipermail/beginners/attachments/20090324/a4482d9b/attachment-0001.htm

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

Message: 3
Date: Tue, 24 Mar 2009 20:12:09 -0500
From: Zachary Turner <divisorthe...@gmail.com>
Subject: [Haskell-beginners] Tutorial/Book with Exercises
To: beginners@haskell.org
Message-ID:
        <478231340903241812q5f317f43ra552da04e4cb8...@mail.gmail.com>
Content-Type: text/plain; charset="iso-8859-1"

Which book or tutorial has the best exercises?  Whenever I learn a language
I like to do tons of exercises, and in fact I keep a list of books with
great exercises.  I currently have Real World Haskell and Programming in
Haskell (Hutton), but I feel the exercises in these books are lacking.
Examples of books with great exercises are ANSI Common Lisp (Graham),
Developing Applications with Ocaml (O'Reilly), The Algorithm Design Manual
(Skiena), and and Enumerative Combinatorics by Stanley (this book is the
king of all books when it comes to exercises).  They shouldn't be
impossible, but at the same time exercises like "what are the types of the
following expressions" are pretty silly.  I think a good book should be
broken into chapters where it takes at least 10 to 20 times as long to
complete the exercises at the end of each chapter than it did to read the
chapter and understand the material in it.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: 
http://www.haskell.org/pipermail/beginners/attachments/20090324/4e7fe0c1/attachment-0001.htm

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

Message: 4
Date: Wed, 25 Mar 2009 05:24:30 +0100
From: ?????????? ?. ????????    <aleks.dimit...@googlemail.com>
Subject: [Haskell-beginners] Event handling in GTK2hs: managing events
        and     global state
To: beginners@haskell.org
Message-ID: <20090325042430.ga4...@brmbr.sfs.uni-tuebingen.de>
Content-Type: text/plain; charset="utf-8"

Hello community,

I'm just diving into my first bigger Haskell problems, and got stuck at a
certain point with gtk2hs. I couldn't find documentation or even small examples
for it, no matter where I looked, so I turn to this list.

My basic problem is that I want a certain action to happen based on the effects
of a side effect; in my case, loading a file into a widget. Together with the
file, I load a data structure, and define an event that will translate clicks on
the widget into some magic on the data structure.

So when I load a file, I do the following:

> loadFile :: GladeXML -> FilePath -> IO ()
> loadFile xml fp = do widget <- xmlGetWidget -- …
>                    -- do stuff with the widget, yield some 'data'
>                    connectId <- widget `on` buttonPressEvent $ handler data
>                    …

(this is a minimal trivial example, to show the crucial point.) So, the handler
step depends on the particular contents of the file. This means, that for every
file I load, I first have to disable the old action, and only then install a new
one, since I generate a new handler every time a file is loaded. Every addition
of a handler gives me a connectId, which is its true name. And, as the gtk2hs
docs inform me, I have to call it by its true name to dispel it.

The gtk2hs docs suggest I 'keep around' the connectId, but herein lies my
problem. The loadFile function can be called from several spots in the
application (and I'd like to keep it that way.) Even if I wrapped loadFile in a
State monad, those entry points to load file (command line, menu, button,
possibly more) have no way of knowing the state of connectId, lest I make it
global (*shudders*) using unsafePerformIO and a Maybe IORef.

Forgive me if I'm missing something obvious, but I have thus far only used
monads for serialized code flows, and not for asynchronous, event-driven
computation.

So the other approach would be (and thanks to mmorrow at freenode for the
idea) to wrap my widget component (if I understood correctly) in a new type that
also keeps track of its connectedId (namely, the event it's been connected to)
via an IORef.  This way the state gets 'hidden' in the IO monad, via IORef. I'd
end up with something like

data WW = WW { widget :: SomeWidget
             , connectId :: IORef (Maybe (ConnectId SomeWidget))
             }

and of course no monads to indicate there's something state-changing going on
(Except the IO monad, which is the underlying monad for the whole brouhaha
anyway.) The above call would look more like:

> main = do …
>           widget <- xmlGetWidget …
>           nothingRef <- newIORef Nothing
>           openButton `onClicked` $ loadFile xml fp (WW widget nothingRef)
>           …
> 
> 
> loadFile :: GladeXML -> FilePath -> WW -> IO ()
> loadFile xml fp (WW widget cid) = -- do stuff, yield some 'data'
>                    ref <- readIORef cid
>                    case ref of 
>                         (Just i) -> signalDisconnect i
>                         Nothing   -> return ()
>                    connectId <- widget `on` buttonPressEvent $
>                                               handler data widget
>                    writeIORef cid $ Just connectId
>                    …


This doesn't strike me as a very elegant way of doing it. I'm sure there is some
nice Haskellery that would make it more beautiful, so I'd like to ask this list
what that might be?

Also, a small plea: the gtk2hs documentation is sorely lacking an example of the
usage of "signalDisconnect". I can provide a working minimal example of this 
solution,
if anyone is interested, so maybe that could serve as a documentation. Though I
still hope that this isn't the best possible way of doing it.

Thanks in advance,
Aleks
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 197 bytes
Desc: not available
Url : 
http://www.haskell.org/pipermail/beginners/attachments/20090325/fad74f60/attachment-0001.bin

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

Message: 5
Date: Wed, 25 Mar 2009 01:18:45 -0400
From: "Brandon S. Allbery KF8NH" <allb...@ece.cmu.edu>
Subject: Re: [Haskell-beginners] Event handling in GTK2hs: managing
        events and      global state
To: ?????????? ?. ???????? <aleks.dimit...@googlemail.com>
Cc: beginners@haskell.org
Message-ID: <82a1b66a-ed3e-4ab4-9e51-f3419d87c...@ece.cmu.edu>
Content-Type: text/plain; charset="utf-8"

On 2009 Mar 25, at 0:24, Александър Л. Димитров  
wrote:
> The gtk2hs docs suggest I 'keep around' the connectId, but herein  
> lies my
> problem. The loadFile function can be called from several spots in the
> application (and I'd like to keep it that way.) Even if I wrapped  
> loadFile in a
> State monad, those entry points to load file (command line, menu,  
> button,
> possibly more) have no way of knowing the state of connectId, lest I  
> make it
> global (*shudders*) using unsafePerformIO and a Maybe IORef.

You can make it "global" without using unsafePerformIO:  Set up a  
ReaderT MyState IO and run the program inside it, after initializing  
your MyState with appropriate IORefs.  You need to lift gtk2hs  
functions, and callbacks have to be wrapped to push them back up into  
the ReaderT:

     curState <- ask
     lift $ widget `on` buttonPressEvent $ runReaderT curState .  
myCallback

The reason you want a ReaderT instead of a StateT is that any state  
not accessed via an IORef can't be propagated between the mainline  
code and callbacks, so you want something that is forced to be read- 
only after initialization except via an IORef stored within it.

Aside:  I've suggested at times that gtk2hs use class MonadIO instead  
of type IO, which would make explicit lifting (and I think "dropping")  
unnecessary.  I never made a formal enhancement suggestion though; I  
should do so.

-- 
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 university    KF8NH


-------------- next part --------------
A non-text attachment was scrubbed...
Name: PGP.sig
Type: application/pgp-signature
Size: 195 bytes
Desc: This is a digitally signed message part
Url : 
http://www.haskell.org/pipermail/beginners/attachments/20090325/b7421f10/PGP.bin

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

_______________________________________________
Beginners mailing list
Beginners@haskell.org
http://www.haskell.org/mailman/listinfo/beginners


End of Beginners Digest, Vol 9, Issue 30
****************************************

Reply via email to