[Haskell-cafe] Re: Beginner SOS

2009-05-28 Thread Benjamin L . Russell
On Wed, 27 May 2009 15:04:36 -0700, Thomas DuBuisson
thomas.dubuis...@gmail.com wrote:

 ?There are links to some great tutorials [1] and IRC
 information where you can get real-time help [2]. ?Also there are some
 good books [3].

 I think most recent learners learned from YAHT [4], Gentle
 Introduction [5], and LYAH [6]. ?I personall read [3]  [4] and
 eventually discovered [7], which is well written but last I checked
 isn't nearly a complete tutorial.

 Thomas

 Did you forget the actual URLs?

Arrghhh,
Indeed - that's what I get for copy/pasting between boxes.

[1] http://haskell.org/haskellwiki/Tutorials
[2] http://haskell.org/haskellwiki/IRC_channel
[3] look for 'Real World Haskell' and 'The Craft of Functional Programming'
[4] http://darcs.haskell.org/yaht/yaht.pdf
[5] http://www.haskell.org/tutorial/
[6] http://learnyouahaskell.com/
[7] http://en.wikibooks.org/wiki/Haskell

Another book that I would recommend is the following:

Programming in Haskell
by Graham Hutton
http://www.cs.nott.ac.uk/~gmh/book.html

Duncan Coutts has written a book review on this title, in which he
highly recommends the book, at the following site:

Book Review: “Programming in Haskell” by Graham Hutton
by Duncan Coutts
http://www.cs.nott.ac.uk/~gmh/book-review.pdf

There is also an eBook version of the above-mentioned title available
at the following site:

eBooks.com - Programming in Haskell eBook
http://www.ebooks.com/ebooks/book_display.asp?IID=307017

Please keep in mind that, unlike most other books and tutorials on
Haskell, neither _Real World Haskell_ nor _Programming in Haskell_
assumes that the reader is highly mathematically-inclined.

-- Benjamin L. Russell
-- 
Benjamin L. Russell  /   DekuDekuplex at Yahoo dot com
http://dekudekuplex.wordpress.com/
Translator/Interpreter / Mobile:  +011 81 80-3603-6725
Furuike ya, kawazu tobikomu mizu no oto. 
-- Matsuo Basho^ 

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


Re: [Haskell-cafe] Design in Haskell?

2009-05-28 Thread Jason Dagit
Hi Dan,

On Mon, May 25, 2009 at 1:22 AM, Dan danielkc...@gmail.com wrote:
 Hi,

 When I was learning to program in imperative languages like Java, there
 were plenty of resources to learn from about how to design large
 programs.   Ideas like the GoF Design Patterns gave useful models that
 one could then scale up.

I think GoF applies even in Haskell.

 Are there such resources for Haskell? As I'm learning the language, I'm
 finding it quite nice to write short programs (e.g. projecteuler,
 Haskell Road, etc.)  But when I try to write something a bit larger, I
 find I'm tripping over myself and having a hard time organizing the
 code coherently.

Many functional programming languages are actually multi-paradigm in
that they support object oriented designs very well.  There are a few
well known differences though.  For example, you won't find people
using the visitor pattern in Lisp/Haskell, but you will find them
using maps, folds, and scrap your boilerplate methods.

Even in Haskell I still find myself thinking a lot about the data
types I will use to represent the problem I'm solving; much like an
object oriented designer would.  One difference though, at this stage,
is that I think about the program as a series of transformations of
data.  I start with a representation of the input, think about how I
want to transform that, then define an intermediate representation.
This pairing of transformations and representations continues until
you have a suitable representation of the output, and then often you
just show it.

Think of type classes as interfaces in Java.  They even support a
restricted variation on subtyping if you chain them together.

One design pattern from the GoF book that works especially well with
Haskell is the interpreter pattern where you make a domain specific
language and solve your problems using that language.

At this point, we're just using a nice functional language the way we
program in other languages.  We can do more though.  The real deep and
interesting designs build on this space.

By exploiting laziness we can make primitives which are more
composable, so it pays to study the way laziness works.  Learn other
people's clever, lazy, solutions to those projecteuler problems. It
can help you write more orthogonal parts in your program so that more
of your program looks like a 'library' that you just happen to call.

The exploits of laziness don't stop there.  You can actually create
data structures which represent control flow abstractions due to
laziness.  Monads, especially the continuation monad, are strong
examples of this.  The beauty of representing control flow
abstractions with data structures in your language is that you can
pass them around, that is they become first class, and also you can
manipulate them.  Monad Transformers being a strong example of this.

In fact, many programs can be built by taking standard monads and
mixing them together, one for each piece.  The easiest way to mix
monads together in this regard is to use monad transformers plus a
feature such as new type deriving.  This gives you a way to piece
together the features you want into a brand new type that hides or
renames the parts that don't make sense.  And the deriving makes it
that much easier, but is not strictly necessary.

Now, still ready to take your designs up a notch?  Well, enter type
system exploits.  There are essentially two directions you can go from
here, a) type classes b) gadts.  Oh, and now we have type families, so
three directions these days.  Using the above you can do all manner of
things, some of which can be turing complete or cause the type checker
to fail to terminate.  People tend to refer to type hackery in units
known as Olegs, with most of us doing just a millioleg design here and
there.  We applied gadt style type hackery in the darcs source code to
remove an entire class of bug, mainly the ones that result from
incorrectly manipulating a sequence of patches.  My thesis explains
the approach we took:
http://blog.codersbase.com/2009/03/25/type-correct-changes-a-safe-approach-to-version-control-implementation/

 Are there any suggestions of wikis, books or particularly
 well-architected and readable projects I could look at to about learn
 larger-scale design in Haskell?

The best advice I can give you, is read/participate on haskell-cafe
and #haskell on irc.freenode.net, and to read the proceedings from
ICFP.  Some really beautiful papers have come out of ICFP over the
years and most of them are quite easy to find on google if you just
look over the list of which papers were presented each year.

This paper is one that I highly recommend.  It teaches you, step by
step, how to stack monads (using transformers) to develop a nice fully
featured evaluator:
http://user.cs.tu-berlin.de/~magr/pub/Transformers.en.html

If you scroll down a bit this page links to all lists of papers
presented at each ICFP:
http://www.icfpconference.org/

Just go over that list and see 

[Haskell-cafe] Re: Who takes care of Haskell mailing lists?

2009-05-28 Thread Benjamin L . Russell
On Wed, 27 May 2009 17:52:17 -0300, Mauricio briqueabra...@yahoo.com
wrote:

I would like to create a mailing list for Portuguese speaking
Haskell programmers. I tried checking haskell.org mailing lists
page, but the only contact e-mail I see is 'mail...@haskell.org',
and a message sent to that address is replied with an automatic
message saying I'm not authorized to use it.

Is there someone I could contact about that?

According to Mailing lists - HaskellWiki (see
http://haskell.org/haskellwiki/Mailing_lists), 

Any problems with haskell or haskell-cafe should be reported to 
haskell-ad...@haskell.org, and any problems with haskell-beginners should be 
reported to dekudekup...@yahoo.com. 

In addition, if you wish to suggest a new mailing list for Haskell, I
would suggest first posting a message suggesting this idea on the
Haskell mailing list (see Haskell Info Page at
http://www.haskell.org/mailman/listinfo/haskell), and then moving the
topic after the first few posting rounds to the Haskell-Cafe mailing
list (this list).

Furthermore, there is a list of haskell.org mailing lists at the
following site:

haskell.org Mailing Lists
http://haskell.org/mailman/listinfo

It may help to notice that one of the mailing lists listed at the
above-mentioned site is the following one for French readers:

Haskell-fr Info Page
http://www.haskell.org/mailman/listinfo/haskell-fr

You may wish to use the existence of this list as a basis for arguing
that a Portuguese mailing list should be created.

Alternatively, there is the option of creating a Haskell-related
mailing list outside of haskell.org, such as the following:

haskell-art Info Page
http://lists.lurk.org/mailman/listinfo/haskell-art

Hope this helps.

-- Benjamin L. Russell
-- 
Benjamin L. Russell  /   DekuDekuplex at Yahoo dot com
http://dekudekuplex.wordpress.com/
Translator/Interpreter / Mobile:  +011 81 80-3603-6725
Furuike ya, kawazu tobikomu mizu no oto. 
-- Matsuo Basho^ 

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


RE: [Haskell-cafe] Template Haskell very wordy w/r/t Decs and Types

2009-05-28 Thread Simon Peyton-Jones
You already have splicing for top level decls. Splicing for local decls is a 
whole different ball game because it brings new *binders* into scope.  For 
example

f = ...g...
g = let $(foo) in ...f...

Is the 'f' inside 'g' the same 'f' as the one bound at top level?  Not 
necessarily, because $(foo) might bind f.  So I can't even do dependency 
analysis to figure out whether f and g are mutually recursive!   It gets harder 
if $(foo) mentions 'f'; and if the definition of 'f' has a declaration splice 
too.

So splicing local decls introduces a new raft of questions whose answers are 
not obvious, and that might require some substantial structural rearrangement 
of GHC.  In particular to the rename and then typecheck strategy.   It's very 
similar to reason that we don't allow splices in patterns.

Bottom line: my nose tells me this is a swamp and I'm steering clear of it for 
now.

Simon

From: Matt Morrow [mailto:moonpa...@gmail.com]
Sent: 28 May 2009 00:08
To: Simon Peyton-Jones
Cc: Ross Mellgren; Haskell Cafe; GHC users
Subject: Re: [Haskell-cafe] Template Haskell very wordy w/r/t Decs and Types

Spectacular!

How difficult would it be to implement splicing in decls? I'm interested in 
having a go at it, and it seems like a perfect time since I can cheat off the 
fresh diff. In particular I'd love to be able to do stuff like this (without 
the current vicious hackery i'm using) (and granted, where i'm splicing is 
somewhat willy-nilly, but some approximation of this):

-

{-# LANGUAGE TemplateHaskell, QuasiQuotes #-}
module DecTest where
import HsDec
import Data.List
import DecTestBoot
import Language.Haskell.TH.Lib
import Language.Haskell.TH.Syntax
import Language.Haskell.Meta.Utils

bootQ :: Q [Dec]
bootQ = bootQFunct
  primQStruct

primQStruct = (''[]
  ,(conT ''[] `appT`)
  ,[|[]|]
  ,[|null|]
  ,[|undefined|]
  ,[|union|]
  ,[|undefined|]
  ,[|undefined|])

bootQFunct
  (primN  :: Name
  ,primQ  :: TypeQ
  - TypeQ  -- exists q. forall a. a - q a
  ,emptyQ :: ExpQ   -- Q a
  ,isEmptyQ   :: ExpQ   -- q a - Bool
  ,insertQ:: ExpQ   -- Int - a - q a - q a
  ,mergeQ :: ExpQ   -- q a - q a - q a
  ,findMinQ   :: ExpQ   -- q a - Maybe (Int, a)
  ,deleteMinQ :: ExpQ)  -- q a - q a

  = do  n - newName a
let primT = varT primN
a = varT n

[$dec|
  data BootQ $(a)
= Nil
| Node {-# UNPACK #-} !Int $(a) ($(primT) (BootQ $(a)))
deriving(Eq,Ord)

  empty :: BootQ $(a)
  isEmpty   :: BootQ $(a) - Bool
  insert:: Int - $(a) - BootQ $(a) - BootQ $(a)
  merge :: BootQ $(a) - BootQ $(a) - BootQ $(a)
  findMin   :: BootQ $(a) - Maybe (Int, $(a))
  deleteMin :: BootQ $(a) - BootQ $(a)

  empty = Nil
  isEmpty Nil = True
  isEmpty   _ = False
  findMin  Nil = Nothing
  findMin (Node n x _) = Just (n, x)
  insert n x q = merge (Node n x $(emptyQ)) q
  merge (Node n1 x1 q1)
(Node n2 x2 q2)
| n1 = n2  = Node n1 x1 ($(insertQ) n2 (Node n2 x2 q2) q1)
| otherwise = Node n2 x2 ($(insertQ) n1 (Node n1 x1 q1) q2)
  merge Nil q  = q
  merge q  Nil = q
  deleteMin  Nil = Nil
  deleteMin (Node _ _ q)
= case $(findMinQ) q of
Nothing - Nil
Just (_, Node m y q1)
  - let q2 = $(deleteMinQ) q
  in Node m y ($(mergeQ) q1 q2)
|]


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


Re: [Haskell-cafe] About the lazy pattern

2009-05-28 Thread Ketil Malde
张旭 stircrazyn...@hotmail.com writes:

 Hi, I am really new to haskell. I am reading A gentle instruction
 to haskell now. And I just cannot understand the chapter below. Is
 there anybody who can gives me some hints about why the pattern
 matching for client is so early? How does the pattern matching
 works here?  

Reading this thread, it occurs to me that I've probably never used a
lazy pattern in my code.  So if you, in spite of the helpful replies
you've got, still have problems understanding lazy patterns, it may be
an option to simply skip this part of the tutorial for now.

(Not that I recommend learning Haskell half-way, mind you, but it did
work for me :-)

-k
-- 
If I haven't seen further, it is by standing in the footprints of giants
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


RE: [Haskell-cafe] Bool as type class to serve EDSLs.

2009-05-28 Thread Simon Peyton-Jones
You are absolutely right about the tantalising opportunity.  I know that 
Lennart has thought quite a bit about this very point when designing his 
Paradise system.  Likewise Conal for Pan.

One difficulty is, I think, that it's easy to get ambiguity.  Eg
ifthenelse (a  b) e1 e2
The (ab) produces a boolean-thing, and ifthenelse consumes it; but which type 
of boolean?  The Expr type?  Real Bools? Or what?

If there was a nice design, then GHC's existing -fno-implicit-prelude flag 
could be extended (again) to desugar if-then-else to the new thing.  But the 
design is unclear, to me anyway.

Simon

| -Original Message-
| From: haskell-cafe-boun...@haskell.org 
[mailto:haskell-cafe-boun...@haskell.org] On
| Behalf Of Sebastiaan Visser
| Sent: 27 May 2009 13:32
| To: Haskell Cafe
| Subject: [Haskell-cafe] Bool as type class to serve EDSLs.
|
| Hello,
|
| While playing with embedded domain specific languages in Haskell I
| discovered the Num type class is a really neat tool. Take this simple
| example embedded language that can embed primitives from the output
| language and can do function application.
|
|  data Expr :: * - * where
|Prim :: String - Expr a
|App  :: Expr (a - b) - Expr a - Expr b
|
| Take these two dummy types to represent things in the output language.
|
|  data MyNum
|  data MyBool
|
| Now it is very easy to create an Num instance for this language:
|
|  primPlus :: Expr (MyNum - MyNum - MyNum)
|  primPlus = Prim prim+
|
|  instance Num (Epxr MyNum) where
|a + b = primPlus `App` a `App` b
|fromInteger = Prim . show
|...
|
| Which allows you to create very beautiful expression for your language
| embedded inside Haskell. The Haskell expression `10 * 5 + 2' produces
| a nice and well typed expression in your embedded domain.
|
| But unfortunately, not everyone in the Prelude is as tolerant as the
| Num instance. Take the Eq and the Ord type classes for example, they
| require you to deliver real Haskell `Bool's. This makes it impossible
| make your DSL an instance of these two, because there are no `Bool's
| only `Expr Bool's.
|
| Which brings me to the point that, for the sake of embedding other
| languages, Haskell's Prelude (or an alternative) can greatly benefit
| from (at least) a Boolean type class like this:
|
| class Boolean a where
|ifthenelse :: a - b - b - b -- Not sure about this
| representation.
|...
|
| And one instance:
|
|  instance Boolean (Expr MyBool) where
|ifthenelse c a b = Prim if-then-else `App` c `App` a `App` b
|
| Now we can change (for example) the Eq type class to this:
|
|  class Eq a where
|(==) :: Boolean b = a - a - b
|(/=) :: Boolean b = a - a - b
|
| For which we can give an implementation for our domain:
|
|  primEq :: Epxr (a - a - MyBool)
|  primEq = Prim ==
|
|  instance Eq (Expr a) where
|a == b = primEq `App` a `App` b
|
| And now we get all functionality from the Prelude that is based on Eq
| (like not, , ||, etc) for free in our domain specific language! Off
| course there are many, many more examples of things from the standard
| libraries that can be generalised in order to serve reuse in EDSLs.
|
| Anyone already working on such a generalized Prelude? I can imagine
| much more domains can benefit from this than my example above. Any
| interesting thoughts or pointers related to this subject?
|
| Gr,
|
| --
| Sebastiaan Visser
|
| ___
| 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


[Haskell-cafe] Re: We tried this functional, higher-order stuff with LISP and look what happened...

2009-05-28 Thread Benjamin L . Russell
On Wed, 27 May 2009 11:31:07 -0700, Jason Dusek
jason.du...@gmail.com wrote:

  What can we say to that? I'm well practiced in handling those
  who reject types outright (Python programmers), those who
  reject what is too different (C programmers), those who can
  not live without objects (Java programmers), those who insist
  we must move everything to message passing (Erlang
  programmers). It's not too often that I meet an embittered
  LISP programmer -- one who's well acquainted with a bold and
  well-supported community of functional programmers whose
  shooting star soon descended to dig a smoking hole in the
  ground.

  Who's to say Haskell (and the more typeful languages in
  general) do not find themselves in the same situation in just
  a few years' time? Is avoiding success at all costs really
  enough?

First off, the real meaning of the slogan Avoid success at all costs
is actually We want lots of users, but not so many that we can't
change anything anymore.  According to [1] (see
http://research.microsoft.com/en-us/um/people/simonpj/papers/history-of-haskell/history.pdf)
(see page 10), 

The fact that Haskell has, thus far, managed the tension between
these two strands of development [as a mature language, and as a 
laboratory in which to explore advanced language design ideas] is 
perhaps due to an accidental virtue: Haskell has not become too 
successful. The trouble with runaway success, such as that of Java, 
is that you get too many users, and the language becomes bogged 
down in standards, user groups, and legacy issues. In contrast, the 
Haskell community is small enough, and agile enough, that it usually 
not only absorbs language changes but positively welcomes them: 
it’s like throwing red meat to hyenas.

One of the authors of the above-mentioned paper, Simon Peyton-Jones,
elaborates in [2] as follows:

... Haskell has a sort of unofficial slogan: avoid success at all 
costs. I think I mentioned this at a talk I gave about Haskell a 
few years back and it’s become sort of a little saying. When you 
become too well known, or too widely used and too successful 
(and certainly being adopted by Microsoft means such a thing), 
suddenly you can’t change anything anymore. You get caught 
and spend ages talking about things that have nothing to do 
with the research side of things.

I’m primarily a programming language researcher, so the fact that 
Haskell has up to now been used for just university types has 
been ideal. Now it’s used a lot in industry but typically by people 
who are generally flexible, and they are a generally a self selected 
rather bright group. What that means is that we could change 
the language and they wouldn’t complain. Now, however, they’re 
starting to complain if their libraries don’t work, which means that 
we’re beginning to get caught in the trap of being too successful.
Haskell has a sort of unofficial slogan: avoid success at all costs

What I’m really trying to say is that the fact Haskell hasn’t become 
a real mainstream programming language, used by millions of 
developers, has allowed us to become much more nimble, and 
from a research point of view, that’s great. We have lots of 
users so we get lots of experience from them. What you want 
is to have a lot of users but not too many from a research point 
of view -- hence the avoid success at all costs. 

What makes you think that Haskell is likely eventually to dig a
smoking hole in the ground?

-- Benjamin L. Russell

[1] Hudak, Paul, Hughes, John, Peyton Jones, Simon, and Wadler,
Philip. A History of Haskell: Being Lazy With Class. San Diego,
California: _The Third ACM SIGPLAN History of Programming Languages
Conference (HOPL-III)_ (2007): 12-1 - 12-55, 2007.
http://research.microsoft.com/en-us/um/people/simonpj/papers/history-of-haskell/history.pdf

[2] Hamilton, Naomi. The A-Z of Programming Languages: Haskell.
_Computerworld_. 19 September 2008. 28 May 2009.
http://www.computerworld.com.au/article/261007/-z_programming_languages_haskell?pp=10
-- 
Benjamin L. Russell  /   DekuDekuplex at Yahoo dot com
http://dekudekuplex.wordpress.com/
Translator/Interpreter / Mobile:  +011 81 80-3603-6725
Furuike ya, kawazu tobikomu mizu no oto. 
-- Matsuo Basho^ 

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


RE: [Haskell-cafe] Bool as type class to serve EDSLs.

2009-05-28 Thread Sittampalam, Ganesh
There are multiple possible classes that you might want under different
circumstances (I think the most interesting issue is whether the class
(==), () etc is in has a fundep from the type of the thing being
compared to the type of the boolean), but if NoImplicitPrelude (or some
other extension) just desugars if-then-else into ifthenelse (with a
default implementation of ifthenelse somewhere) I think that would be
enough.

Of course once you've got ifthenelse you find yourself wanting explicit
desugaring of pattern matching (could view patterns help here?),
recursion (into an explicit use of fix), etc...

Cheers,

Ganesh

Simon Peyton-Jones wrote:
 You are absolutely right about the tantalising opportunity.  I know
 that Lennart has thought quite a bit about this very point when
 designing his Paradise system.  Likewise Conal for Pan.  
 
 One difficulty is, I think, that it's easy to get ambiguity.  Eg
 ifthenelse (a  b) e1 e2
 The (ab) produces a boolean-thing, and ifthenelse consumes it; but
 which type of boolean?  The Expr type?  Real Bools? Or what? 
 
 If there was a nice design, then GHC's existing -fno-implicit-prelude
 flag could be extended (again) to desugar if-then-else to the new
 thing.  But the design is unclear, to me anyway.  
 
 Simon
 
 -Original Message-
 From: haskell-cafe-boun...@haskell.org
 [mailto:haskell-cafe-boun...@haskell.org] On Behalf Of Sebastiaan
 Visser Sent: 27 May 2009 13:32
 To: Haskell Cafe
 Subject: [Haskell-cafe] Bool as type class to serve EDSLs.
 
 Hello,
 
 While playing with embedded domain specific languages in Haskell I
 discovered the Num type class is a really neat tool. Take this simple
 example embedded language that can embed primitives from the output
 language and can do function application.
 
  data Expr :: * - * where
Prim :: String - Expr a
App  :: Expr (a - b) - Expr a - Expr b
 
 Take these two dummy types to represent things in the output
 language. 
 
  data MyNum
  data MyBool
 
 Now it is very easy to create an Num instance for this language:
 
  primPlus :: Expr (MyNum - MyNum - MyNum)  primPlus = Prim
 prim+ 
 
  instance Num (Epxr MyNum) where
a + b = primPlus `App` a `App` b
fromInteger = Prim . show
...
 
 Which allows you to create very beautiful expression for your
 language embedded inside Haskell. The Haskell expression `10 * 5 +
 2' produces a nice and well typed expression in your embedded domain.
 
 But unfortunately, not everyone in the Prelude is as tolerant as the
 Num instance. Take the Eq and the Ord type classes for example, they
 require you to deliver real Haskell `Bool's. This makes it impossible
 make your DSL an instance of these two, because there are no `Bool's
 only `Expr Bool's. 
 
 Which brings me to the point that, for the sake of embedding other
 languages, Haskell's Prelude (or an alternative) can greatly benefit
 from (at least) a Boolean type class like this:
 
 class Boolean a where
ifthenelse :: a - b - b - b -- Not sure about this
representation. ...
 
 And one instance:
 
  instance Boolean (Expr MyBool) whereifthenelse c a b = Prim
 if-then-else `App` c `App` a `App` b
 
 Now we can change (for example) the Eq type class to this:
 
  class Eq a where
(==) :: Boolean b = a - a - b
(/=) :: Boolean b = a - a - b
 
 For which we can give an implementation for our domain:
 
  primEq :: Epxr (a - a - MyBool)
  primEq = Prim ==
 
  instance Eq (Expr a) where
a == b = primEq `App` a `App` b
 
 And now we get all functionality from the Prelude that is based on Eq
 (like not, , ||, etc) for free in our domain specific language! Off
 course there are many, many more examples of things from the standard
 libraries that can be generalised in order to serve reuse in EDSLs.
 
 Anyone already working on such a generalized Prelude? I can imagine
 much more domains can benefit from this than my example above. Any
 interesting thoughts or pointers related to this subject?
 
 Gr,
 
 --
 Sebastiaan Visser
 
 ___
 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


=== 
 Please access the attached hyperlink for an important electronic 
communications disclaimer: 
 http://www.credit-suisse.com/legal/en/disclaimer_email_ib.html 
 
=== 
 
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Bool as type class to serve EDSLs.

2009-05-28 Thread Lennart Augustsson
Here's what I usually use.  As Simon points out, ambiguity is lurking
as soon as you use conditional.  You can avoid it a fundep, but that's
not necessarily what you want either.

-- | Generalization of the 'Bool' type.  Used by the generalized 'Eq' and 'Ord'.
class Boolean bool where
()  :: bool - bool - bool   -- ^Logical conjunction.
(||)  :: bool - bool - bool   -- ^Logical disjunction.
not   :: bool - bool   -- ^Locical negation.
false :: bool   -- ^Truth.
true  :: bool   -- ^Falsity.
fromBool :: Bool - bool-- ^Convert a 'Bool' to the
generalized Boolean type.
fromBool b = if b then true else false

-- | Generalization of the @if@ construct.
class (Boolean bool) = Conditional bool a where
conditional :: bool - a - a - a -- ^Pick the first argument if
the 'Boolean' value is true, otherwise the second argument.

class (Boolean bool) = Eq a bool {- x | a - bool -} where
(==) :: a - a - bool
(/=) :: a - a - bool

x /= y  =  not (x == y)
x == y  =  not (x /= y)


On Thu, May 28, 2009 at 8:14 AM, Simon Peyton-Jones
simo...@microsoft.com wrote:
 You are absolutely right about the tantalising opportunity.  I know that 
 Lennart has thought quite a bit about this very point when designing his 
 Paradise system.  Likewise Conal for Pan.

 One difficulty is, I think, that it's easy to get ambiguity.  Eg
        ifthenelse (a  b) e1 e2
 The (ab) produces a boolean-thing, and ifthenelse consumes it; but which 
 type of boolean?  The Expr type?  Real Bools? Or what?

 If there was a nice design, then GHC's existing -fno-implicit-prelude flag 
 could be extended (again) to desugar if-then-else to the new thing.  But the 
 design is unclear, to me anyway.

 Simon

 | -Original Message-
 | From: haskell-cafe-boun...@haskell.org 
 [mailto:haskell-cafe-boun...@haskell.org] On
 | Behalf Of Sebastiaan Visser
 | Sent: 27 May 2009 13:32
 | To: Haskell Cafe
 | Subject: [Haskell-cafe] Bool as type class to serve EDSLs.
 |
 | Hello,
 |
 | While playing with embedded domain specific languages in Haskell I
 | discovered the Num type class is a really neat tool. Take this simple
 | example embedded language that can embed primitives from the output
 | language and can do function application.
 |
 |  data Expr :: * - * where
 |    Prim :: String - Expr a
 |    App  :: Expr (a - b) - Expr a - Expr b
 |
 | Take these two dummy types to represent things in the output language.
 |
 |  data MyNum
 |  data MyBool
 |
 | Now it is very easy to create an Num instance for this language:
 |
 |  primPlus :: Expr (MyNum - MyNum - MyNum)
 |  primPlus = Prim prim+
 |
 |  instance Num (Epxr MyNum) where
 |    a + b = primPlus `App` a `App` b
 |    fromInteger = Prim . show
 |    ...
 |
 | Which allows you to create very beautiful expression for your language
 | embedded inside Haskell. The Haskell expression `10 * 5 + 2' produces
 | a nice and well typed expression in your embedded domain.
 |
 | But unfortunately, not everyone in the Prelude is as tolerant as the
 | Num instance. Take the Eq and the Ord type classes for example, they
 | require you to deliver real Haskell `Bool's. This makes it impossible
 | make your DSL an instance of these two, because there are no `Bool's
 | only `Expr Bool's.
 |
 | Which brings me to the point that, for the sake of embedding other
 | languages, Haskell's Prelude (or an alternative) can greatly benefit
 | from (at least) a Boolean type class like this:
 |
 | class Boolean a where
 |    ifthenelse :: a - b - b - b         -- Not sure about this
 | representation.
 |    ...
 |
 | And one instance:
 |
 |  instance Boolean (Expr MyBool) where
 |    ifthenelse c a b = Prim if-then-else `App` c `App` a `App` b
 |
 | Now we can change (for example) the Eq type class to this:
 |
 |  class Eq a where
 |    (==) :: Boolean b = a - a - b
 |    (/=) :: Boolean b = a - a - b
 |
 | For which we can give an implementation for our domain:
 |
 |  primEq :: Epxr (a - a - MyBool)
 |  primEq = Prim ==
 |
 |  instance Eq (Expr a) where
 |    a == b = primEq `App` a `App` b
 |
 | And now we get all functionality from the Prelude that is based on Eq
 | (like not, , ||, etc) for free in our domain specific language! Off
 | course there are many, many more examples of things from the standard
 | libraries that can be generalised in order to serve reuse in EDSLs.
 |
 | Anyone already working on such a generalized Prelude? I can imagine
 | much more domains can benefit from this than my example above. Any
 | interesting thoughts or pointers related to this subject?
 |
 | Gr,
 |
 | --
 | Sebastiaan Visser
 |
 | ___
 | 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


[Haskell-cafe] Re: What's the problem with iota's type signature?

2009-05-28 Thread Gracjan Polak
michael rice nowgate at yahoo.com writes:

 I've been digging into this stuff for months and it's still tripping me up.

For exploration use GHCi. It can tell you the type of thing you have written. It
has command to tell you type of thing, the :t. See here:

Prelude let double x = Just (x + x)
Prelude :t double
double :: (Num a) = a - Maybe a

Prelude let iota n = [1..n]
Prelude :t iota
iota :: (Num t, Enum t) = t - [t]

Prelude [3,4,5] = iota
[1,2,3,1,2,3,4,1,2,3,4,5]

You don't have to guess then, Haskell compiler can do the guessing for you. It
is called type inference.

-- 
Gracjan


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


Re: [Haskell-cafe] Re: Error message reform (was: Strange type error with associated type synonyms)

2009-05-28 Thread Claus Reinke

One user's view of error message history, perhaps helpful to reformers:-)

Once upon a time, Hugs tended to have better error messages than GHC.

They still weren't perfect, mostly when begginners where confronted with
messages referring to advanced concepts - eg, Simon Thompson had a list 
of translations of the kind if Hugs reports this, it most likely means that,
especially targetted to beginners in his courses, ie users who where unlikely 
to want things like 'Num (a-b)' instances, or find non-existing semicolons. 

(the advice to focus on the error location usually means that either the 
error message is misleading or too difficult for the user to interpret - it

is a standard fallback in all programming language implementations,
but no more than that; if we rely on it too often, the messages aren't
doing their job)

Even for more advanced users, it was helpful to get messages from
several implementations (at least Hugs and GHC) for tricky cases, just
to get different views from which to piece together a picture. This, sadly,
is not as well supported these days as it used to be, but getting multiple
opinions on type errors is still useful advice (if your code can be handled
by multiple implementations, or if a single implementation can offer multiple
views, eg, beginner/advanced or top-down/bottom-up or ..).

Then Simon PJ invested a lot of energy into improving GHC's error 
messages, so the balance changed. Error message complaints didn't
stop, though, and the error messages were improved further, with 
more text, and suggestions for possible fixes, etc.


The suggestions are sometimes misleading, and I've felt there has 
been too much weight on narrative text, to the exclusion of actual 
type information (it is a programming language, after all, so why 
don't the error messages give type signatures for context instead of 
trying to talk me through it in natural language, without further 
references to types!-), but discussions like the present show that 
Simon has been on the right track with that, for many users.


Still, I would really like a just the facts, please mode for GHC, 
with less text and more type signatures (especially for the contexts 
of type mismatches). Error messages simply not including the

information I need has become my main issue with GHC messages,
and seems to be a common thread over many tickets and threads
apparently discussing phrasing (eg, expected/inferred: who expects
and why, and what is the inference based on?).

Somewhere in between, much research has focussed on type errors,
and how to report them in general, and implementations like Helium 
have set out to target beginners with simpler error messages. (*)


As for fixes, concrete suggestions are most likely to be adopted,
but sometimes it just isn't clear how to improve the situation, and
sometimes, there is no single best solution (which has spawned
countless interesting papers on type-error reporting;-).

It you want to help, file tickets for messages you find unhelpful,
and make suggestions for possible improvements. Unfortunately,
there doesn't seem to be an error message component in GHC's
trac, so querying for relevant tickets is not straightforward. Simon
keeps a partial list of error message related tickets here (keeping
track of trac tickets - meta-trac?-):

http://hackage.haskell.org/trac/ghc/wiki/Status/SLPJ-Tickets

Just, please, keep in mind that there is no one-size-fits-all:
improving a message for one group of users might well make
it less useful for another group.

Claus

(*) A beginner mode for Haskell systems has often been suggested,
   even before Helium. Instead, error messages, and even language
   design decisions have been constrained by trying to serve everyone
   with a single mode. I'd have thought that Helium, and Dr Scheme,
   have sufficiently demonstrated the value of having separate levels
   of a language and the corresponding error messages.


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


Re: [Haskell-cafe] Lazy Parsing

2009-05-28 Thread Malcolm Wallace
Henning Thielemann schlepp...@henning-thielemann.de wrote:

 I don't think that it is in general possible to use the same parser
 for lazy and strict parsing, just because of the handling of parser
 failure.

Polyparse demonstrates that you can mix-and-match lazy parsers with
strict parsers in the different parts of a grammar (by choosing whether
to use applicative or monadic style).  You can also switch between lazy
or strict interpretations of the applicative parts of your grammar (by
changing the import that decides which version of the parser primitives
is in scope).

 I also used polyparse for lazy parsing, but I found it unintuitive how
 to make a parser lazy.

It can certainly be tricky, and requires a certain amount of
experimentation.  I think the difficulties are mainly due to the mix of
lazy (applicative) and strict (monadic) styles in different
non-terminals.  A parser that you intend to be lazy, may turn out to be
stricter than you hope, because of the strictness of another parser that
it depends upon.

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


RE: [Haskell-cafe] Type class context propagation investigation[MESSAGE NOT SCANNED]

2009-05-28 Thread Paul Keir
Thanks. GHC at one stage suggested I add (Num a) =
to my Num instance (after I'd added (Eq a) = to my Eq
instance) and I didn't make the connection.


-Original Message-
From: Ryan Ingram [mailto:ryani.s...@gmail.com]
Sent: Thu 28/05/2009 01:18
To: Paul Keir
Cc: haskell-cafe@haskell.org
Subject: Re: [Haskell-cafe] Type class context propagation 
investigation[MESSAGE NOT SCANNED]
 
Think of classes like data declarations; an instance with no context
is a constant, and one with context is a function.  Here's a simple
translation of your code into data; this is very similar to the
implementation used by GHC for typeclasses:

 data EqDict a = EqDict { eq :: a - a - Bool }
 data ShowDict a = ShowDict { show :: a - String }
 data NumDict a = NumDict { num_eq :: EqDict a, num_show :: ShowDict a, plus 
 :: a - a - a }

The goal of the compiler is to turn your instance declarations into
these structures automatically.  Here's a translation of your original
instance:

 eq_foo :: EqDict (Foo a)
 eq_foo = EqDict { eq = undefined }

 show_foo :: ShowDict (Foo a)
 show_foo = ShowDict { show = undefined }

 num_foo :: NumDict (Foo a)
 num_foo = NumDict { num_eq = eq_foo, num_show = show_foo, plus = undefined }

Now if you add a constraint on the Eq instance, this means that eq
from eq_foo might refer to eq in the dictionary for a.  How do we
get that dictionary?  We just pass it as an argument!

 eq_foo :: EqDict a - EqDict (Foo a)
 eq_foo eq_a = EqDict { eq = undefined }

However, you don't have a similar constraint on the Num instance:

 num_foo :: NumDict (Foo a)
 num_foo = NumDict { num_eq = eq_foo something, num_show = show_foo, plus = 
 undefined }

The compiler wants to fill in something, but it can't; it doesn't
have a dictionary of the type EqDict a.  So it tells you so, saying
that Eq a is missing!

Once you add the (Eq a) constraint to the Num instance, it works:

 num_foo :: EqDict a - NumDict (Foo a)
 num_foo eq_a = NumDict { num_eq = eq_foo eq_a, num_show = show_foo, plus = 
 undefined }

You can also add a (Num a) constraint instead, and the compiler can
use it to get the Eq instance out:

 num_foo :: NumDict a - NumDict (Foo a)
 num_foo num_a = NumDict { num_eq = eq_foo (num_eq num_a), num_show = 
 show_foo, plus = undefined }

Of course, I'm glossing over the interesting details of the search,
but the basic idea is to attempt to fill in the blanks in these
definitions.

  -- ryan

On Wed, May 27, 2009 at 2:10 PM, Paul Keir pk...@dcs.gla.ac.uk wrote:
 Hi,

 How does the context of a class instance declaration affect its subclasses?

 The Num class instance outlined below has its requirement for Eq and Show
 satisfied on the preceding lines, and the code will compile. But if I, say,
 add an (Eq a) constraint to the Eq instance, in preparation for a simple
 (==) definition, I find that the Num instance declaration is left lacking.
 If I add the same (Eq a) constraint now to Num, calm is restored.

 data Foo a = F a

 instance Eq (Foo a) where
  (==) = undefined

 instance Show (Foo a) where
  show = undefined

 instance Num (Foo a)
  (+) = undefined
  ... etc.

 The thing that confuses me with this is that it seems like Num knows that
 an (Eq a) context has been applied, and so what it sees as a problem, is
 somehow also the solution. Any advice/rules of thumb? Does this situation
 occur elsewhere? How do these constraints propagate?

 Thanks,
 Paul

 ___
 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] Bool as type class to serve EDSLs.

2009-05-28 Thread Claus Reinke

Of course once you've got ifthenelse you find yourself wanting explicit
desugaring of pattern matching (could view patterns help here?),


Could you be more specific about what you want there, perhaps
with a small example? I recognize the other problems from my own
forays into EDSLs, but I'm not sure I recognize this one. If you want
to reuse the existing 'lhs=rhs' syntax for patterns specific to your EDSL,
both QuasiQuotes and ViewPatterns might help, if you want to be able 
to compose patterns beyond the limitations of that syntax, one of the

proposals and libraries for first-class patterns might help, adding
functionality at the expense of more complex syntax.


recursion (into an explicit use of fix), etc...


Yes, in principle (you're thinking of sharing, and of lifting pure code?). 
In practice, too much machinery is attached to the existing 'let' to 
make that likely.


But this reminds me of another closely related issue: GHC offers a
lot of help in moving stuff from compiler-baked-in to library-provided,
but almost none of the mechanisms works at the level of syntax/AST
(where most other languages do their meta-programming/language
extension support). 

RULES and compiler plugins work on core, where it is too late to 
do EDSL-specific source-level rewrites, TH requires quoted things 
to parse and type-check in the un-extended language, making it less 
useful for EDSL-specific language extensions. For instance, think of 
the arrows syntax: there doesn't seem to be any way that this could 
have been defined in a library, so it had to be baked into GHC?


QuasiQuotes seem to be the only feature that gives source-level
control, and they suffer from the lack of easily available parsers
(eg, if my EDSL requires an extension of some Haskell construct, 
I'd like to be able to reuse the Haskell parsers for the baseline). 
There is a package on hackage targetting that issue (haskell-src-meta), 
but it relies on a second frontend (haskell-src-ext), and only works

with a single GHC version.

Claus



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


Re: [Haskell-cafe] Re: What's the problem with iota's type signature?

2009-05-28 Thread Lee Duhem
On Thu, May 28, 2009 at 5:19 PM, Gracjan Polak gracjanpo...@gmail.com wrote:
 You don't have to guess then, Haskell compiler can do the guessing for you.

It isn't guess, Haskell compiler (like GHC) gets these types by (type)
inference, as you said :-)

lee

 It is called type inference.
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] the problem of design by negation

2009-05-28 Thread Magnus Therning
On Thu, May 28, 2009 at 5:59 AM, Conal Elliott co...@conal.net wrote:
 Thanks for bringing in this angle, David.

 My preference is for honest and humble practice and documentation of
 negative design.  Instead of saying that something won't work, can't
 work, is impossible etc (or rephrased via must, only, etc), I'd like
 honest admissions like I couldn't figure out X, I got stuck on Y, etc.
 After all, someone else might get further.  Or, in the rare cases, when
 something actually is impossible, say so prove it.

Yes, this angle is important, escpecially if you like me read a lot of
code and end up thinking why is this code so complicated, there must
be an easier way.  I often feel that thinking like that prevents
quick understanding of the code, simply because my brain is
pre-occupied with solving the problem more elegantly while trying to
understand what is going on :-)

Often a particular solution isn't impossible to use (i.e. the words
can't, won't etc shouldn't be used), instead solutions aren't as
good as others when resource constraints into account.  Of course the
negative reasons must be backed up with data (sometimes rough
estimates are enough), but this brings me to other pet peeves of mine
at work, the general lack of non-functional requirements and
prototyping with performance tests.

/M

-- 
Magnus Therning(OpenPGP: 0xAB4DFBA4)
magnus@therning.org  Jabber: magnus@therning.org
http://therning.org/magnus identi.ca|twitter: magthe
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] About the lazy pattern

2009-05-28 Thread Petr Pudlak
Hi Ryan, thanks for a nice and thorough explanation. I had trouble
understanding the section of the tutorial as well. Maybe it would deserve to
rewrite to something a bit simpler?

Anyhow, I'd like to ask: Is there a reason for which pattern matching for
single-constructor data types isn't lazy by default? For example, why do I have
to write

 weird ~(x,y) = (1,x)
 crazy = weird crazy

when the compiler knows that the type (x,y) has just the single constructor,
and could automatically introduce the additional laziness without any risk?

Petr

 Hi nemo.  I had a lot of trouble with that section of the tutorial as
 well, and I believe that once you get it, a lot of Haskell becomes a
 lot simpler.
 
 The way I eventually figured it out is using this idealized execution
 model for Haskell: you just work by rewriting the left side of a
 function to its right side.  The only question is figuring out *which*
 function to rewrite!
 
 Here's a simpler example:
 
  f 0 = 0
  f x = x+1
 
  g (x:xs) = error urk
  g [] = 2
  const a b = a
 
  ex1 = const (f 1) (g [2,3])
  ex2 = f (const (g []) (g [1,2]))
 
 Lets say you wanted to know the value of ex1; you just use rewriting
 
 ex1
 -- rewrite using ex1
 = const (f 1) (g [2,3])
 -- rewrite using const
 = f 1
 -- rewrite using f (second pattern)
 = 1+1
 -- rewrite using +
 = 2
 
 But lets say we picked a different order to rewrite...
 
 ex1
 -- rewrite using ex1
 = const (f 1) (g [2,3])
 -- rewrite using g
 = const (f 1) (error urk)
 -- rewrite using error
 computation stops
 
 Of course this is bad, and it was obviously wrong to evaluate g first
 (because const is lazy).  So one heuristic we always use is rewrite
 the leftmost application first which avoids this problem.  But lets
 try that rule on ex2!
 
 ex2
 -- rewrite using ex2
 = f (const (g []) (g [1,2]))
 -- rewrite using f
 = ?
 
 Unfortunately, now we don't know which pattern to match!  So we have
 to pick a different thing to rewrite.  The next rule is that, if the
 thing you want to rewrite has a pattern match, look at the argument
 for the patterns being matched and rewrite them instead, using the
 same leftmost first rule:
 
 f (const (g []) (g [1,2]))
 -- trying to pattern match f's first argument
 -- rewrite using const
 = f (g [])
 -- still pattern matching
 -- rewrite using g
 = f 2
 -- now we can match
 -- rewrite using f (second pattern)
 = 2+1
 -- rewrite using +
 = 3
 
 So, back to the original question (I'm rewriting the arguments to
 client and server for clarity)
 
  reqs = client init resps
  resps = server reqs
  client v (rsp:rsps) = v : client (next rsp) rsps
  server (rq:rqs) = process rq : server rqs
 
 Lets say we are trying to figure out the value of resps, to print
 all the responses to the screen:
 
 resps
 -- rewrite using resps
 = server reqs
 -- pattern match in server
 -- rewrite reqs
 = server (client init resps)
 -- pattern match in server
 -- pattern match also in client
 -- rewrite using resps
 = server (client init (server reqs))
 -- pattern match in server, client, then server
 -- rewrite using reqs
 = server (client init (server (client init resps)))
 
 You see that we are in a loop now; we are stuck trying to pattern
 match and we will never make any progress!
 
 The lazy pattern says trust me, this pattern will match, you can
 call me on it later if it doesn't!
 
  reqs = client init resps
  resps = server reqs
  client v (rsp:rsps) = v : client (next rsp) rsps
  server (rq:rqs) = process rq : server rqs
 
 resps
 -- rewrite resps
 = server reqs
 -- server wants to pattern match, rewrite reqs
 = server (client init resps)
 -- Now, the lazy pattern match says this will match, wait until later
 -- rewrite using client!
 = let (rsp:rsps) = resps
in server (init : client (next rq) rqs)
 -- rewrite using server
 = let (rsp:rsps) = resps
in process init : server (client (next rq) rqs)
 
 We now have a list node, so we can print the first element and
 continue (which requires us to know the code for process and next,
 but you get the idea, I hope!)
 
 Now of course, you can lie to the pattern matcher:
 
  next x = x + 1
  init = 5
 
 client init []
 -- rewrite using client
 = let (rsp0:rsps0) = []
in init : client (next rsp0) rsps0
 -- rewrite using init
 = let (rsp0:rsps0) = []
in 5 : client (next rsp0) rsps0
 
 -- print 5 and continue to evaluate...
let (rsp0:rsps0) = []
in client (next rsp0) rsps0
 -- rewrite using client
 = let
 (rsp0:rsps0) = []
 (rsp1:rsps1) = rsps0
in (next rsp0) : client (next rsp1) rsps1
 -- rewrite using next
 = let
 (rsp0:rsps0) = []
 (rsp1:rsps1) = rsps0
in rsp0+1 : client (next rsp1) rsps1
 -- + wants to pattern match on its first argument
 -- rewrite using rsp0
 computation stops, pattern match failure, (rsp0:rsps0) does not match []
 
 For this reason, many people (myself included) consider it bad style
 to use lazy/irrefutable pattern matches on data types with more than
 one constructure.  But 

Re: [Haskell-cafe] About the lazy pattern

2009-05-28 Thread Max Bolingbroke
2009/5/28 Petr Pudlak d...@pudlak.name:
 Hi Ryan, thanks for a nice and thorough explanation. I had trouble
 understanding the section of the tutorial as well. Maybe it would deserve to
 rewrite to something a bit simpler?

 Anyhow, I'd like to ask: Is there a reason for which pattern matching for
 single-constructor data types isn't lazy by default? For example, why do I 
 have
 to write

 weird ~(x,y) = (1,x)
 crazy = weird crazy

 when the compiler knows that the type (x,y) has just the single constructor,
 and could automatically introduce the additional laziness without any risk?

I think this is really two questions:

1) Why can't the /compiler/ add extra laziness automatically?
Because it's not semantics preserving:

weird (x, y) = (1, x)
lazyWeird ~(x, y) = (1, x)

weird undefined = undefined
lazyWeird undefined = (1, undefined)

Of course, it's arguable as to whether turning non-terminating
programs into terminating ones is really that big of a deal. In fact,
some transformations in GHC already make this kind of change for
optimization purposes (albeit only to things of function type, where
the waters are murkier).

Even if it were semantics preserving, making things MORE lazy is not
likely to lead to performance improvement, so I doubt the compiler
would want to do this.

2) Why isn't product pattern matching lazy by default in Haskell?
I can't give a definitive answer, but I suspect that the reason is
that the Haskell design team didn't want adding an extra constructor
to your type definition to change the semantics of all the pattern
matches in your program. Seems pretty sensible to me :-)

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


Re: [Haskell-cafe] Data.Binary and little endian encoding

2009-05-28 Thread Khudyakov Alexey
On Thursday 28 of May 2009 07:52:56 David Leimbach wrote:
 Sorry took so long to get back... Thank you for the response.  Been really
 busy lately :-)

 There are also a lot of 9P implementations in many languages that you can
 interoperate with:

 http://9p.cat-v.org/implementations

Thank you for that link. I didn't find it earlier. But actually I asked what 
are you trying to write? 

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


Re: [Haskell-cafe] Bool as type class to serve EDSLs.

2009-05-28 Thread Sebastiaan Visser
Or overloading the `whitespace operator' for several kinds of  
application.


On May 28, 2009, at 9:50 AM, Augustsson, Lennart wrote:

And explicit desugaring of list syntax.

-Original Message-
From: Sittampalam, Ganesh [mailto:ganesh.sittampa...@credit- 
suisse.com]

Sent: 28 May 2009 08:46
To: Simon Peyton-Jones; Sebastiaan Visser; Haskell Cafe
Cc: Augustsson, Lennart
Subject: RE: [Haskell-cafe] Bool as type class to serve EDSLs.

There are multiple possible classes that you might want under  
different

circumstances (I think the most interesting issue is whether the class
(==), () etc is in has a fundep from the type of the thing being
compared to the type of the boolean), but if NoImplicitPrelude (or  
some

other extension) just desugars if-then-else into ifthenelse (with a
default implementation of ifthenelse somewhere) I think that would be
enough.

Of course once you've got ifthenelse you find yourself wanting  
explicit

desugaring of pattern matching (could view patterns help here?),
recursion (into an explicit use of fix), etc...

Cheers,

Ganesh

Simon Peyton-Jones wrote:

You are absolutely right about the tantalising opportunity.
...

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


Re: [Haskell-cafe] Stack overflow

2009-05-28 Thread Bertram Felgenhauer
Krzysztof Skrzętnicki wrote:
 2009/5/27 Bertram Felgenhauer bertram.felgenha...@googlemail.com:
  I wrote:
  Krzysztof Skrzętnicki wrote:
  The code for modifying the counter:
  (\ msg - atomicModifyIORef ioref (\ cnt - (cntMsg cnt msg,(
 
  atomicModifyIORef does not force the new value of the IORef.
  If the previous contents of the IORef is x, the new contents
  will be a thunk,
 
    (\ cnt - (cntMsg cnt msg,())) x
 
  Sorry, it's slightly worse than that. The contents becomes
 
     sel_0 (\ cnt - (cntMsg cnt msg, ())) x
 
  where sel_0 is basically an RTS internal version of fst.
 
  Instead of reading the new value of the IORef, you could also force the
  old one:
 
     atomicModifyIORef ioref (\ cnt - (cntMsg cnt msg, msg)) = (return $!)
 
 
 Thanks for the tip, although it seems tricky to get it right. I wonder
 why there is no strict version of atomicModifyIORef?

Something like this?

-- | Stricter version of 'atomicModifyIORef', which prevents building
--   up huge thunks in the 'IORef' due to repeated modification.
--   Unlike 'atomicModifyIORef', 'atomicModifyIORef'' may block.
atomicModifyIORef' :: IORef a - (a - (a, b)) - IO b
atomicModifyIORef' ioref f = do
res - atomicModifyIORef ioref f
new - readIORef ioref
new `seq` return res

(The step that may block is forcing the new value - if another thread is
already evaluating part of the thunk, the currently executing thread
will block, waiting for the other thread to finish.)

 Dually there might be a strict version of IORef datatype.

One interesting feature of atomicModifyIORef is that its implementation
is lock-free, and never blocks (which affects exception handling):
replacing the old value by the new value is done with compare-and-swap
operation in a tight loop. Each iteration executes very quickly because
all it does is replace the reference to the old value in the new thunk.

With a strict IORef, the time window between reading the old value and
storing the new value would become arbitrarily large, because you'd have
to force the new value before exchanging it with the old value. So a
reasonable implementation would have to use locks instead, I think,
making atomicModifyIORef more expensive, and less useful in contexts
that block exceptions.

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


Re[2]: [Haskell-cafe] Bool as type class to serve EDSLs.

2009-05-28 Thread Bulat Ziganshin
Hello Lennart,

Thursday, May 28, 2009, 11:57:09 AM, you wrote:

 -- | Generalization of the 'Bool' type.  Used by the generalized 'Eq' and 
 'Ord'.
 class Boolean bool where
 ()  :: bool - bool - bool   -- ^Logical conjunction.
 (||)  :: bool - bool - bool   -- ^Logical disjunction.

i use another approach which imho is somewhat closer to interpretation
of logical operations in dynamic languages (lua, ruby, perl):

a ||| b | isDefaultValue a = b
| otherwise= a

a  b | isDefaultValue a = defaultValue
| otherwise= b

-- Class of types having default value:
classDefaults a  where defaultValue :: a
instance Defaults () where defaultValue = ()
instance Defaults Bool   where defaultValue = False
instance Defaults [a]where defaultValue = []
instance Defaults (a-a)   where defaultValue = id
instance Defaults (Maybe a)where defaultValue = Nothing
instance Defaults (a-IO a)where defaultValue = return
instance Defaults a = Defaults (IO a) where defaultValue = return defaultValue
instance Defaults Int  where defaultValue = 0
instance Defaults Integer  where defaultValue = 0
instance Defaults Double   where defaultValue = 0

-- Class of types that can be tested for default value:
classTestDefaultValue a   where isDefaultValue :: a - Bool
instance TestDefaultValue Boolwhere isDefaultValue = not
instance TestDefaultValue [a] where isDefaultValue = null
instance TestDefaultValue Int where isDefaultValue = (==0)
instance TestDefaultValue Integer where isDefaultValue = (==0)
instance TestDefaultValue Double  where isDefaultValue = (==0)


usage examples:

return$ (isDir  addTrailingPathSeparator) filespec
openWebsite$ (isWindows  windosifyPath) file
let options =
  (compressionEnabled   cvt -m   compressionMethod')++
  (encryptionEnabledcvt -ae= 
encryptionMethod')++encryptionOptions++
  (protectionEnabledcvt -rr  protectionMethod')
let another_msg = ciphers ||| not encrypted
let msg = ftLocked footer  yes ||| no


-- 
Best regards,
 Bulatmailto:bulat.zigans...@gmail.com

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


RE: [Haskell-cafe] Type class context propagation investigation

2009-05-28 Thread Paul Keir
Thanks Wren, that makes sense.

Ryan Ingram wrote:
 Think of classes like data declarations; an instance with no context
 is a constant, and one with context is a function.  Here's a simple
 translation of your code into data; this is very similar to the
 implementation used by GHC for typeclasses:
 
  data EqDict a = EqDict { eq :: a - a - Bool }
  data ShowDict a = ShowDict { show :: a - String }
  data NumDict a = NumDict { num_eq :: EqDict a, num_show :: ShowDict a, plus 
  :: a - a - a }
 
 The goal of the compiler is to turn your instance declarations into
 these structures automatically.

Another way of explaining this, if you're a Curry--Howard fan, is that 
the compiler is looking for a proof that the type belongs to the class, 
where = is logical implication. This is very similar to how Prolog 
searches for proofs, if you're familiar with logic programming.

Classes declare the existence of logical predicates, along with the form 
of what a proof of the predicate looks like. Instances declare a 
particular proof (or family of proofs if there are free type variables).


Thus, the Num class is declared as,

 class (Eq a, Show a) = Num a where ...

which says: for any type |a|, we can prove |Num a| if (and only if) we 
can prove |Eq a| and |Show a|, and can provide definitions for all the 
functions in the class using only the assumptions that |Eq a|, |Show a|, 
and |Num a|.


When you declare,

 instance Eq b = Eq (Foo b) where ...

you're providing a proof of |Eq b = Eq (Foo b)|. That is, you can 
provide a conditional proof of |Eq (Foo b)|, given the assumption that 
you have a proof of |Eq b|.

Notice how the context for instances is subtly different from the 
context for classes. For instances you're saying that this particular 
proof happens to make certain assumptions; for classes you're saying 
that all proofs require these assumptions are valid (that is, providing 
the functions isn't enough to prove membership in the class).


Later on you declare,

 instance Num (Foo b) where ...

but remember that this proof must have the same form as is declared by 
the class definition. This means that you must have proofs of |Eq (Foo 
b)| and |Show (Foo b)|. Unfortunately, you don't actually have a proof 
of |Eq (Foo b)|, you only have a proof of |Eq b = Eq (Foo b)|. In order 
to use that proof you must add the |Eq b| assumption to this proof as well:

 instance Eq b = Num (Foo b) where ...

When the compiler is complaining about the original one, what it's 
telling you is that the |Num (Foo b)| proof can never exist because you 
can never provide it with a proof of |Eq (Foo b)| in order to fulfill 
its requirements.

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


Re: [Haskell-cafe] Data.Binary and little endian encoding

2009-05-28 Thread David Leimbach
On Thu, May 28, 2009 at 5:42 AM, Khudyakov Alexey alexey.sklad...@gmail.com
 wrote:

 On Thursday 28 of May 2009 07:52:56 David Leimbach wrote:
  Sorry took so long to get back... Thank you for the response.  Been
 really
  busy lately :-)
 
  There are also a lot of 9P implementations in many languages that you can
  interoperate with:
 
  http://9p.cat-v.org/implementations
 
 Thank you for that link. I didn't find it earlier. But actually I asked
 what
 are you trying to write?


I'm trying to implement the protocol, so that I can implement other things
on top of that.

I'm also trying to figure out how bad/good Haskell Binary IO really is that
it's been addressed a few times differently :-)



 --
   Khudyakov Alexey
 ___
 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


[Haskell-cafe] Re: Strange type error with associated type synonyms

2009-05-28 Thread Achim Schneider
Bulat Ziganshin bulat.zigans...@gmail.com wrote:

 Hello Achim,
 
 Thursday, May 28, 2009, 1:34:55 AM, you wrote:
 
  Error: type of x is Integer
   while type of read argument should be String
  
  The problem with this is that the compiler can't know whether or not
  the type of arguments to read should be a String, as someone could
  have messed up read's signature.
 
 i don't understood what you mean, can you give an example?
 
Error : type of x is String
  while the type of an argument to read should be Integer

, given that, somewhere, you have

read :: Integer - a

, which is, of course, wrong, and that's the point.


-- 
(c) this sig last receiving data processing entity. Inspect headers
for copyright history. All rights reserved. Copying, hiring, renting,
performance and/or quoting of this signature prohibited.


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


[Haskell-cafe] gtk2hs, TreeView and CellRenderer

2009-05-28 Thread Zefirov Sergey
As far as I can tell, there is not way to create CellRenderer that could 
include icons with the text (I think it is because of incompatibilities of 
Haskell type classes and Gtk inheritance hierarchy).

Is it a good way to use CellRendererPixbuf and render to pixbufs using Cairo? I 
think my TreeView hierarchies won't be very big, around 1000 items for a while.
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Data.Binary and little endian encoding

2009-05-28 Thread Don Stewart
leimy2k:
 I'm also trying to figure out how bad/good Haskell Binary IO really is that
 it's been addressed a few times differently :-)

FWIW Binary IO as implemented in Data.Binary is widely used in our
production systems at Galois. I'd be fairly confident in it.

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


[Haskell-cafe] Re: Introducing Instances in GHC point releases

2009-05-28 Thread Simon Marlow

On 27/05/2009 22:02, Henning Thielemann wrote:


My proposal is thus: Discourage orphan instances! If you encounter that
an instance is missing and it is a canonical one, it should be added to
the package that defines the type or the class. If there are several
choices for the implementation then the package where the instance would
belong to should document that. Then programmers should find a consensus
which of the choices they prefer. If you cannot wait for an official
adaption of the required instance, then you must work with newtype
wrappers.


Quite.  I argued the no orphan instances in libraries position on the 
libraries list last year, here's the start of the (longish) thread:


http://www.haskell.org/pipermail/libraries/2008-September/010618.html

We ought to have a guidelines for API design section of the wiki 
somewhere, so we could put this in it.


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


Re: [Haskell-cafe] Data.Binary and little endian encoding

2009-05-28 Thread John Van Enk


 I'm trying to implement the protocol, so that I can implement other things
 on top of that.

 I'm also trying to figure out how bad/good Haskell Binary IO really is that
 it's been addressed a few times differently :-)



FWIW, I've used Data.Binary extensively and have found it a joy to work
with. I've used it to serialize/deserialize ethernet packets in real time
for a VPN implementation and have never had a problem. It's quite fast and
robust.

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


[Haskell-cafe] Re: Data.Binary and little endian encoding

2009-05-28 Thread David Leimbach
On Thursday, May 28, 2009, Don Stewart d...@galois.com wrote:
 leimy2k:
 I'm also trying to figure out how bad/good Haskell Binary IO really is that
 it's been addressed a few times differently :-)

 FWIW Binary IO as implemented in Data.Binary is widely used in our
 production systems at Galois. I'd be fairly confident in it.


Fair enough.   I am just new to the interface, wondering if I should
try matching responses by pulling apart via Get, or the bit syntax
package.


 -- Don

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


Re: [Haskell-cafe] Re: Introducing Instances in GHC point releases

2009-05-28 Thread Henning Thielemann


On Thu, 28 May 2009, Simon Marlow wrote:

Quite.  I argued the no orphan instances in libraries position on the 
libraries list last year, here's the start of the (longish) thread:


http://www.haskell.org/pipermail/libraries/2008-September/010618.html


I remember. What I propose additionally is, that, when orphan instances 
are banned, we can allow addition of instances with the A.B.* version 
range just like this is allowed for all other language elements.


We ought to have a guidelines for API design section of the wiki somewhere, 
so we could put this in it.


That's currently spread across Category:Style.
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Re: Data.Binary and little endian encoding

2009-05-28 Thread John Van Enk


 Fair enough.   I am just new to the interface, wondering if I should
 try matching responses by pulling apart via Get, or the bit syntax
 package.



I'm assming you have some 'data Foo = ...'? If this is the case, you're
probably okay writing an instance of Binary for Foo and using encode/decode.
That's all I've had to do and had superb performance.

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


[Haskell-cafe] Re: Error message reform (was: Strange type error with associated type synonyms)

2009-05-28 Thread Achim Schneider
John Dorsey hask...@colquitt.org wrote:

 As another native English speaker, I found expected/inferred very
 intuitive when I was new to GHC, and to Haskell.  I even think that
 expected/inferred helped me form my intuition about Haskell's type
 inference.

First off, me too, and I'm not a native speaker.

OTOH, while expected is not ambiguous, inferred is: After all, both
types are inferred.

I opt for

expected/encountered

-- 
(c) this sig last receiving data processing entity. Inspect headers
for copyright history. All rights reserved. Copying, hiring, renting,
performance and/or quoting of this signature prohibited.


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


Re: [Haskell-cafe] Data.Binary and little endian encoding

2009-05-28 Thread Duncan Coutts
On Thu, 2009-05-28 at 12:08 -0400, John Van Enk wrote:
  
 I'm trying to implement the protocol, so that I can implement
 other things on top of that.  
  
 I'm also trying to figure out how bad/good Haskell Binary IO
 really is that it's been addressed a few times differently :-)
  
  
 FWIW, I've used Data.Binary extensively and have found it a joy to
 work with. I've used it to serialize/deserialize ethernet packets in
 real time for a VPN implementation and have never had a problem. It's
 quite fast and robust.

Is that code available? We could do with something serious for
benchmarking the binary package, especially if we go for any major
re-engineering.

If it's not available publicly perhaps you might share it privately. Don
and I have discussed a few times writing a paper on the design and
implementation of a binary library.

Duncan


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


Re: [Haskell-cafe] Re: Data.Binary and little endian encoding

2009-05-28 Thread David Leimbach
On Thu, May 28, 2009 at 9:17 AM, John Van Enk vane...@gmail.com wrote:


 Fair enough.   I am just new to the interface, wondering if I should
 try matching responses by pulling apart via Get, or the bit syntax
 package.



 I'm assming you have some 'data Foo = ...'? If this is the case, you're
 probably okay writing an instance of Binary for Foo and using encode/decode.
 That's all I've had to do and had superb performance.



encode/decode do Big Endian, and 9P does little endian.

From the man page:

Each message consists of a sequence of bytes. Two–, four–, and eight–byte
fields hold unsigned integers represented in little–endian order (least
significant byte first).

encode/decode just won't work for me as a result, as they assume the
not-so-aptly-named (at least in this case) network byte order.  Since I'm
not Rob Pike, or Ken Thompson or any of the Plan 9 guys, I can't tell you
why they chose little endian for this.

(I should note that I sometimes work with CAN hardware, and depending on
what people want to put on the line, little endian creeps in there too, so
this issue will have to be dealt with here as well, if I am to use
Data.Binary)

I've got (typing from memory, forgive syntax errors)

module Nine (Message) where

{-- missing imports --}

notag = putWord16le -1

-- Message type field values
-- from: http://plan9.bell-labs.com/sources/plan9/sys/include/fcall.h
tversion = 100
rversion = 101
rerror = 107


-- only 9P2000 is being handled so some constructors are simple
data Message = Tversion
| Rversion {size :: Int, tag :: Int,  msize :: Int,
version :: String}
| Rerror {message :: String}  -- maybe this should
be Maybe ByteString?
...

instance Binary Message where
put Tversion = putWord32le 16  tversion  notag  msize  9P2000
put Rversion = putWord32le 16  rversion  notag  msize  9P2000
get = do size - getWord32le
 tag - getWord8
 case tag of
  rversion - do msize - getWord32le
   version - getRemainingLazyByteString
   return (Rversion size tag msize (C.unpack
version))

 ===

I'm beginning to feel the Get Monad is not going to be as nice as if I had
some bit-syntax for determining what type of return message I'm getting.
 Any T message can be met with the paired R response, or an Rerror
message, with a detailed description of what went wrong.  My instance of get
is looking like it's going to be pretty nasty :-)

The first message in any 9p session is Tversion with Rversion or Rerror
response.  There's optional authentication hooks via Tauth/Rauth, and then
the filesystem namespace navigation operation messages.

Dave

/jve

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


Re: [Haskell-cafe] Re: Data.Binary and little endian encoding

2009-05-28 Thread Don Stewart
leimy2k:
 encode/decode do Big Endian, and 9P does little endian. 
 
 From the man page:
 
 Each message consists of a sequence of bytes. Two , four , and eight byte
 fields hold unsigned integers represented in little endian order (least
 significant byte first).
 
 encode/decode just won't work for me as a result, as they assume the
 not-so-aptly-named (at least in this case) network byte order.  Since I'm 
 not
 Rob Pike, or Ken Thompson or any of the Plan 9 guys, I can't tell you why they
 chose little endian for this. 


I think you misunderstand the API: encode and decode *use whatever the
underlying instance for your data type uses*. If you write an instance
that uses the little endian primitives, that is what I will use.

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


Re: [Haskell-cafe] About the lazy pattern

2009-05-28 Thread Ryan Ingram
The main change I would make is to rename the arguments to
client/server; they overload the same names (reqs/resps) as the top
level declarations above, so it's very easy to get confused while
reading it.

Partially, I think this is just a hard concept to understand;
struggling to figure it out definitely helped me understand the
language in general.

One idea is to draw a graph showing the cycle of dependences: client
- resps, resps - server, server - reqs, reqs - client, and
explaining that we break the dependency cycle in two ways:

(1) the init parameter to client allows reqs to output its first
message before any processing has done
(2) but in order to do so, it needs to be able to delay the pattern match.

Perhaps rewrite client first in this way:

client init rsps = init : (rest rsps) where
   rest (r:rs) = client (next r) rs

then show the additional syntactic sugar for delaying the pattern
match until needed?

It also might help to make the example concrete by implementing a
simple next and process.

  -- ryan

On Thu, May 28, 2009 at 4:18 AM, Petr Pudlak d...@pudlak.name wrote:
 Hi Ryan, thanks for a nice and thorough explanation. I had trouble
 understanding the section of the tutorial as well. Maybe it would deserve to
 rewrite to something a bit simpler?

 Anyhow, I'd like to ask: Is there a reason for which pattern matching for
 single-constructor data types isn't lazy by default? For example, why do I 
 have
 to write

 weird ~(x,y) = (1,x)
 crazy = weird crazy

 when the compiler knows that the type (x,y) has just the single constructor,
 and could automatically introduce the additional laziness without any risk?

    Petr

 Hi nemo.  I had a lot of trouble with that section of the tutorial as
 well, and I believe that once you get it, a lot of Haskell becomes a
 lot simpler.

 The way I eventually figured it out is using this idealized execution
 model for Haskell: you just work by rewriting the left side of a
 function to its right side.  The only question is figuring out *which*
 function to rewrite!

 Here's a simpler example:

  f 0 = 0
  f x = x+1

  g (x:xs) = error urk
  g [] = 2
  const a b = a

  ex1 = const (f 1) (g [2,3])
  ex2 = f (const (g []) (g [1,2]))

 Lets say you wanted to know the value of ex1; you just use rewriting

 ex1
 -- rewrite using ex1
 = const (f 1) (g [2,3])
 -- rewrite using const
 = f 1
 -- rewrite using f (second pattern)
 = 1+1
 -- rewrite using +
 = 2

 But lets say we picked a different order to rewrite...

 ex1
 -- rewrite using ex1
 = const (f 1) (g [2,3])
 -- rewrite using g
 = const (f 1) (error urk)
 -- rewrite using error
 computation stops

 Of course this is bad, and it was obviously wrong to evaluate g first
 (because const is lazy).  So one heuristic we always use is rewrite
 the leftmost application first which avoids this problem.  But lets
 try that rule on ex2!

 ex2
 -- rewrite using ex2
 = f (const (g []) (g [1,2]))
 -- rewrite using f
 = ?

 Unfortunately, now we don't know which pattern to match!  So we have
 to pick a different thing to rewrite.  The next rule is that, if the
 thing you want to rewrite has a pattern match, look at the argument
 for the patterns being matched and rewrite them instead, using the
 same leftmost first rule:

 f (const (g []) (g [1,2]))
 -- trying to pattern match f's first argument
 -- rewrite using const
 = f (g [])
 -- still pattern matching
 -- rewrite using g
 = f 2
 -- now we can match
 -- rewrite using f (second pattern)
 = 2+1
 -- rewrite using +
 = 3

 So, back to the original question (I'm rewriting the arguments to
 client and server for clarity)

  reqs = client init resps
  resps = server reqs
  client v (rsp:rsps) = v : client (next rsp) rsps
  server (rq:rqs) = process rq : server rqs

 Lets say we are trying to figure out the value of resps, to print
 all the responses to the screen:

 resps
 -- rewrite using resps
 = server reqs
 -- pattern match in server
 -- rewrite reqs
 = server (client init resps)
 -- pattern match in server
 -- pattern match also in client
 -- rewrite using resps
 = server (client init (server reqs))
 -- pattern match in server, client, then server
 -- rewrite using reqs
 = server (client init (server (client init resps)))

 You see that we are in a loop now; we are stuck trying to pattern
 match and we will never make any progress!

 The lazy pattern says trust me, this pattern will match, you can
 call me on it later if it doesn't!

  reqs = client init resps
  resps = server reqs
  client v (rsp:rsps) = v : client (next rsp) rsps
  server (rq:rqs) = process rq : server rqs

 resps
 -- rewrite resps
 = server reqs
 -- server wants to pattern match, rewrite reqs
 = server (client init resps)
 -- Now, the lazy pattern match says this will match, wait until later
 -- rewrite using client!
 = let (rsp:rsps) = resps
    in server (init : client (next rq) rqs)
 -- rewrite using server
 = let (rsp:rsps) = resps
    in process init : server (client (next rq) rqs)

 We now 

Re: [Haskell-cafe] Data.Binary and little endian encoding

2009-05-28 Thread Johan Tibell
On Thu, May 28, 2009 at 6:34 PM, Duncan Coutts
duncan.cou...@worc.ox.ac.ukwrote:

 If it's not available publicly perhaps you might share it privately. Don
 and I have discussed a few times writing a paper on the design and
 implementation of a binary library.


I would definitely like to read such a paper. Except for Don's blog entries
there's precious little written on the design of high performance Haskell
libraries.

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


Re: [Haskell-cafe] Re: Data.Binary and little endian encoding

2009-05-28 Thread John Van Enk
Writing instances encode/decode that use either little endian or big endian
(or mixed!) is trivial... see attached file.

I don't see where your problem is...

On Thu, May 28, 2009 at 12:35 PM, David Leimbach leim...@gmail.com wrote:



   On Thu, May 28, 2009 at 9:17 AM, John Van Enk vane...@gmail.com wrote:


 Fair enough.   I am just new to the interface, wondering if I should
 try matching responses by pulling apart via Get, or the bit syntax
 package.



 I'm assming you have some 'data Foo = ...'? If this is the case, you're
 probably okay writing an instance of Binary for Foo and using encode/decode.
 That's all I've had to do and had superb performance.



 encode/decode do Big Endian, and 9P does little endian.

 From the man page:

 Each message consists of a sequence of bytes. Two–, four–, and eight–byte
 fields hold unsigned integers represented in little–endian order (least
 significant byte first).

 encode/decode just won't work for me as a result, as they assume the
 not-so-aptly-named (at least in this case) network byte order.  Since I'm
 not Rob Pike, or Ken Thompson or any of the Plan 9 guys, I can't tell you
 why they chose little endian for this.

 (I should note that I sometimes work with CAN hardware, and depending on
 what people want to put on the line, little endian creeps in there too, so
 this issue will have to be dealt with here as well, if I am to use
 Data.Binary)

 I've got (typing from memory, forgive syntax errors)

 module Nine (Message) where

 {-- missing imports --}

 notag = putWord16le -1

 -- Message type field values
 -- from: http://plan9.bell-labs.com/sources/plan9/sys/include/fcall.h
 tversion = 100
 rversion = 101
 rerror = 107


 -- only 9P2000 is being handled so some constructors are simple
 data Message = Tversion
 | Rversion {size :: Int, tag :: Int,  msize :: Int,
 version :: String}
 | Rerror {message :: String}  -- maybe this should
 be Maybe ByteString?
 ...

  instance Binary Message where
 put Tversion = putWord32le 16  tversion  notag  msize  9P2000
 put Rversion = putWord32le 16  rversion  notag  msize  9P2000
 get = do size - getWord32le
  tag - getWord8
  case tag of
   rversion - do msize - getWord32le
version - getRemainingLazyByteString
return (Rversion size tag msize
 (C.unpack version))

  ===

 I'm beginning to feel the Get Monad is not going to be as nice as if I had
 some bit-syntax for determining what type of return message I'm getting.
  Any T message can be met with the paired R response, or an Rerror
 message, with a detailed description of what went wrong.  My instance of get
 is looking like it's going to be pretty nasty :-)

 The first message in any 9p session is Tversion with Rversion or Rerror
 response.  There's optional authentication hooks via Tauth/Rauth, and then
 the filesystem namespace navigation operation messages.

 Dave

   /jve



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




-- 
/jve


binaryTest.hs
Description: Binary data
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Stack overflow

2009-05-28 Thread Krzysztof Skrzętnicki
On Thu, May 28, 2009 at 14:41, Bertram Felgenhauer
bertram.felgenha...@googlemail.com wrote:
 Krzysztof Skrzętnicki wrote:
 2009/5/27 Bertram Felgenhauer bertram.felgenha...@googlemail.com:
  I wrote:
  Krzysztof Skrzętnicki wrote:
  The code for modifying the counter:
  (\ msg - atomicModifyIORef ioref (\ cnt - (cntMsg cnt msg,(
 
  atomicModifyIORef does not force the new value of the IORef.
  If the previous contents of the IORef is x, the new contents
  will be a thunk,
 
    (\ cnt - (cntMsg cnt msg,())) x
 
  Sorry, it's slightly worse than that. The contents becomes
 
     sel_0 (\ cnt - (cntMsg cnt msg, ())) x
 
  where sel_0 is basically an RTS internal version of fst.
 
  Instead of reading the new value of the IORef, you could also force the
  old one:
 
     atomicModifyIORef ioref (\ cnt - (cntMsg cnt msg, msg)) = (return $!)
 

 Thanks for the tip, although it seems tricky to get it right. I wonder
 why there is no strict version of atomicModifyIORef?

 Something like this?

 -- | Stricter version of 'atomicModifyIORef', which prevents building
 --   up huge thunks in the 'IORef' due to repeated modification.
 --   Unlike 'atomicModifyIORef', 'atomicModifyIORef'' may block.
 atomicModifyIORef' :: IORef a - (a - (a, b)) - IO b
 atomicModifyIORef' ioref f = do
    res - atomicModifyIORef ioref f
    new - readIORef ioref
    new `seq` return res

 (The step that may block is forcing the new value - if another thread is
 already evaluating part of the thunk, the currently executing thread
 will block, waiting for the other thread to finish.)

 Dually there might be a strict version of IORef datatype.

 One interesting feature of atomicModifyIORef is that its implementation
 is lock-free, and never blocks (which affects exception handling):
 replacing the old value by the new value is done with compare-and-swap
 operation in a tight loop. Each iteration executes very quickly because
 all it does is replace the reference to the old value in the new thunk.

 With a strict IORef, the time window between reading the old value and
 storing the new value would become arbitrarily large, because you'd have
 to force the new value before exchanging it with the old value. So a
 reasonable implementation would have to use locks instead, I think,
 making atomicModifyIORef more expensive, and less useful in contexts
 that block exceptions.

We may as well drop the 'atomic' keyword and provide a warning about
possible blocking of thread. The end user may forkIO the modification
if he wants to.

I modified the code as follows, it works now:
(\ msg - atomicModifyIORef ioref (\ cnt - (cntMsg cnt msg,cnt)) =
(return $!))

Thank you all for your help!

Best regards

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


[Haskell-cafe] attaching a ghci session to another process

2009-05-28 Thread Kevin Smith
I am starting to get more involved with haskell programming and I'd like to
create a program where I can use the interactive loop in ghci to run a
haskell functions that create graphics in a separate openGL window.  This
would be a separate interactive window from the terminal i am running ghci
in and have it's own event-loop/thread of execution.   For a very simple
example, I would have a haskel function called w = window , which when
executed would create an openGL window (inside a seprate window manager
shell) and return an identifier to it.   A call to another fuinction might
be obj = cube [..] w whch would draw an cube in the window. etc.   The
openGL would have it's own event loop running to handle mouse/keyboard and
refresh events which means that I would be able to manipuolate the camera
with the mouse (pan, zoom, rotate etc.). This would be separate fromt he
ghci input loop running in the original terminal window.

The graphics part of this is easy for me, I have this implemented in other
langauges, but what i would like to do is create a functional programming
environment for prototyping in 3D, so I would like to have a haskell session
which I can attach to this 3D environment.

Any comments/feedback on the architecture/design of such a program would be
appreciated.

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


[Haskell-cafe] Parsec float

2009-05-28 Thread Bartosz Wójcik
Hi Everybody (especially Parsec Creator),

is there any reason why float parses only positive numbers?

I find following defition:

float   = lexeme floating   ? float

floating= do{ n - decimal
; fractExponent n
}

If floating was defined like

floating= do{ n - integer ...

or

floating= do{ n - int ...

instead  then it would parse negative ones as well.  

Best regards,
Bartek


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


[Haskell-cafe] Parsec float

2009-05-28 Thread Malcolm Wallace

is there any reason why float parses only positive numbers?


It is usual in parsing libraries to separate the recognition of a  
leading sign from recognition of the number itself: the sign-only  
parser can be reused in many contexts,  e.g. in the Haskell'98 Numeric  
library, there is


 readSigned :: Real a = ReadS a - ReadS a

which takes a secondary parser as its argument.  You can instantiate  
that argument to any of


 readDec   :: Num a = ReadS a
 readHex   :: Num a = ReadS a
 readFloat :: Num a = ReadS a

etc.  I do not know if the equivalent of readSigned exists in  
Parsec, but it in polyparse's Text.Parse module, it is called  
parseSigned, rather unsurprisingly.


Regards,
Malcolm

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


[Haskell-cafe] ANNOUNCE: Hac φ: Haskell hackathon in Philadelphia, July 24-26

2009-05-28 Thread Brent Yorgey
Greetings,

I am very pleased to officially announce Hac phi, a Haskell
hackathon/get-together to be held July 24-26 at the University of
Pennsylvania in Philadelphia.  The hackathon will officially kick off
at 2:30 Friday afternoon, and go until 5pm on Sunday (with breaks for
sleep, of course).  Thanks to everyone who has already expressed
interest in attending, it's shaping up to be a fun event.  I want to
stress that everyone is welcome---you do not have to be a Haskell guru
to attend!  Helping hack on someone else's project could be a great
way to increase your Haskell-fu.

If you plan on coming, please officially register [1], even if you
already put your name on the wiki.  Registration, travel, lodging and
many other details can now be found on the Hac phi wiki [2].

We're also looking for a few people interested in giving short (15-20
min.) talks, probably on Saturday afternoon.  Anything of interest to
the Haskell community is fair game---a project you've been working on,
a paper, a quick tutorial.  If you'd like to give a talk, add it on
the wiki [3].

Hope to see you in Philadelphia!

-The Hac φ team

[1] http://haskell.org/haskellwiki/Hac_%CF%86/Register
[2] http://haskell.org/haskellwiki/Hac_%CF%86
[3] http://haskell.org/haskellwiki/Hac_%CF%86/Talks

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


[Haskell-cafe] Re: Error message reform (was: Strange type error with associated type synonyms)

2009-05-28 Thread Simon Michael

Achim Schneider wrote:

expected/encountered


Expected/actual ? Familiar to users of test frameworks.

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


[Haskell-cafe] Re: Who takes care of Haskell mailing lists?

2009-05-28 Thread Maurí­cio

Benjamin,


I would like to create a mailing list for Portuguese speaking
Haskell programmers. (...)



According to Mailing lists - HaskellWiki (see
http://haskell.org/haskellwiki/Mailing_lists),


Thanks for your comprehensive reports. However, I did
took all measures you sugested.


Any problems with haskell or haskell-cafe should be

 reported to haskell-ad...@haskell.org, (...)

OK. Sent also to haskell-admin. I misunderstood that address was
only for problems, sorry for that.


In addition, if you wish to suggest a new mailing list for Haskell, I
would suggest first posting a message suggesting this idea (...)


See this thread:

http://www.haskell.org/pipermail/haskell-cafe/2009-May/061694.html


It may help to notice that one of the mailing lists listed at the
above-mentioned site is the following one for French readers: (...)
You may wish to use the existence of this list as a basis for arguing
that a Portuguese mailing list should be created.


I think that is a good point. I said that in my message to the first
address I found. My sugestion was to name the list 'haskell-pt',
and the description could be Lista de discussão para os falantes
da língua portuguesa (in Portuguese) or Mailing list for Portuguese
speakers all over the world (in English, correct if necessary).



Alternatively, there is the option of creating a Haskell-related
mailing list outside of haskell.org, such as the following:


I thought about that. But there are hundreds of millions of
Portuguese speaking people, and probably a few thousands Haskell
programmers, maybe 5 or 10 universities using it for undergraduate
teaching, so I thought it would not be fair that I would be the
list owner. I may not be doing Haskell in a few months, or die in
a car accident, who knows? :)

Best,
Maurício

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


[Haskell-cafe] Problem w/YAHT code example

2009-05-28 Thread michael rice
This code, from YAHT (Section 8.4.2, PDF pg. 119 of 192) seems to have a 
problem. Code below.

Michael

=

[mich...@localhost ~]$ ghci
GHCi, version 6.10.1: http://www.haskell.org/ghc/  :? for help
Loading package ghc-prim ... linking ... done.
Loading package integer ... linking ... done.
Loading package base ... linking ... done.
Prelude :l graph
[1 of 1] Compiling Main ( graph.hs, interpreted )

graph.hs:6:24: lexical error at character '\8217'
Failed, modules loaded: none.

==

Prelude data Graph v e = Graph [(Int,v)] [(Int,Int,e)]

search :: Graph v e - Int - Int - Maybe [Int]
search g@(Graph vl el) src dst
    | src == dst = Just [src]
    | otherwise = search’ el
    where search’ [] = Nothing
  search’ ((u,v,_):es)
  | src == u =
    case search g v dst of
  Just p - Just (u:p)
  Nothing - search’ es
  | otherwise = search’ es







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


Re: [Haskell-cafe] Problem w/YAHT code example

2009-05-28 Thread Andrew Wagner
I'm not sure what you're using at the end of the identifier search', but
it needs to be the single quote that's on the same key as the double quotes.
I suspect that's where it's blowing up.

On Thu, May 28, 2009 at 9:56 PM, michael rice nowg...@yahoo.com wrote:

 This code, from YAHT (Section 8.4.2, PDF pg. 119 of 192) seems to have a
 problem. Code below.

 Michael

 =

 [mich...@localhost ~]$ ghci
 GHCi, version 6.10.1: http://www.haskell.org/ghc/  :? for help
 Loading package ghc-prim ... linking ... done.
 Loading package integer ... linking ... done.
 Loading package base ... linking ... done.
 Prelude :l graph
 [1 of 1] Compiling Main ( graph.hs, interpreted )

 graph.hs:6:24: lexical error at character '\8217'
 Failed, modules loaded: none.

 ==

 Prelude data Graph v e = Graph [(Int,v)] [(Int,Int,e)]

 search :: Graph v e - Int - Int - Maybe [Int]
 search g@(Graph vl el) src dst
 | src == dst = Just [src]
 | otherwise = search’ el
 where search’ [] = Nothing
   search’ ((u,v,_):es)
   | src == u =
 case search g v dst of
   Just p - Just (u:p)
   Nothing - search’ es
   | otherwise = search’ es






 ___
 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: Data.Binary and little endian encoding

2009-05-28 Thread David Leimbach
On Thu, May 28, 2009 at 11:39 AM, John Van Enk vane...@gmail.com wrote:

 Writing instances encode/decode that use either little endian or big endian
 (or mixed!) is trivial... see attached file.

 I don't see where your problem is...



Inexperience, lack of enough contiguous time to digest everything at once
(till now),  thank you for your most detailed example!  This should be
wiki'd.

Dave


 On Thu, May 28, 2009 at 12:35 PM, David Leimbach leim...@gmail.comwrote:



   On Thu, May 28, 2009 at 9:17 AM, John Van Enk vane...@gmail.comwrote:


 Fair enough.   I am just new to the interface, wondering if I should
 try matching responses by pulling apart via Get, or the bit syntax
 package.



 I'm assming you have some 'data Foo = ...'? If this is the case, you're
 probably okay writing an instance of Binary for Foo and using encode/decode.
 That's all I've had to do and had superb performance.



 encode/decode do Big Endian, and 9P does little endian.

 From the man page:

 Each message consists of a sequence of bytes. Two–, four–, and
 eight–byte fields hold unsigned integers represented in little–endian order
 (least significant byte first).

 encode/decode just won't work for me as a result, as they assume the
 not-so-aptly-named (at least in this case) network byte order.  Since I'm
 not Rob Pike, or Ken Thompson or any of the Plan 9 guys, I can't tell you
 why they chose little endian for this.

 (I should note that I sometimes work with CAN hardware, and depending on
 what people want to put on the line, little endian creeps in there too, so
 this issue will have to be dealt with here as well, if I am to use
 Data.Binary)

 I've got (typing from memory, forgive syntax errors)

 module Nine (Message) where

 {-- missing imports --}

 notag = putWord16le -1

 -- Message type field values
 -- from: http://plan9.bell-labs.com/sources/plan9/sys/include/fcall.h
 tversion = 100
 rversion = 101
 rerror = 107


 -- only 9P2000 is being handled so some constructors are simple
 data Message = Tversion
 | Rversion {size :: Int, tag :: Int,  msize ::
 Int, version :: String}
 | Rerror {message :: String}  -- maybe this should
 be Maybe ByteString?
 ...

  instance Binary Message where
 put Tversion = putWord32le 16  tversion  notag  msize 
 9P2000
 put Rversion = putWord32le 16  rversion  notag  msize 
 9P2000
 get = do size - getWord32le
  tag - getWord8
  case tag of
   rversion - do msize - getWord32le
version - getRemainingLazyByteString
return (Rversion size tag msize
 (C.unpack version))

  ===

 I'm beginning to feel the Get Monad is not going to be as nice as if I had
 some bit-syntax for determining what type of return message I'm getting.
  Any T message can be met with the paired R response, or an Rerror
 message, with a detailed description of what went wrong.  My instance of get
 is looking like it's going to be pretty nasty :-)

 The first message in any 9p session is Tversion with Rversion or Rerror
 response.  There's optional authentication hooks via Tauth/Rauth, and then
 the filesystem namespace navigation operation messages.

 Dave

   /jve



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




 --
 /jve

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


Re: [Haskell-cafe] What's the problem with iota's type signature?

2009-05-28 Thread wren ng thornton

michael rice wrote:

Yeah, I went back and tried double again, though I'd swear I got the dang thing 
to compile  (and run) w/o errors.

I guess I meant Num. So Num is a class and Int and Integer are types? What are 
the other classes? Docs?

Unification, for me, is pattern matching ala Prolog. What's the meaning in 
Haskell? Docs?

I've been digging into this stuff for months and it's still tripping me up. 
Very frustrating.



As others have mentioned, using GHCi can give you a lot of information. 
GHCi commands begin with a colon followed by the command (kinda like 
vi), whereas anything not beginning with a colon is treated as a Haskell 
expression to be evaluated. The :? command will list all the GHCi 
commands, which is a good place to start.


The :type command takes a Haskell expression and prints the type 
inferred for it. You can also use the command :set +t which will make 
GHCi print the type after evaluating each expression; you may want to 
use this until you get the hang of things. The :info command takes a 
whitespace separated list of identifiers and will print their type and 
other information (e.g. what module it comes from, what type class a 
function belongs to, all the functions that are members of a type class, 
fixity of operators,...)



As far as type classes and the like, there are a bunch. Hoogle[1] is an 
excellent API search engine for looking up this kind of stuff. Just 
enter the name of a function, type class, data type, or enter a type 
signature. The results give links to the online Haddock documentation 
(either GHC official docs, or Hackage docs).



Unification is used when doing type inference. It's the same unification 
as in Prolog, only at the type level. Because of the way inference 
works, it happens that the |a| and |b| type variables must be unified 
for both of the functions you gave. A whole lot more can be said here, 
though I'm not sure how much you care :)  The Wikipedia page on 
Hindley--Milner[2] gives a good starting point, though Haskell's type 
inference has more bells and whistles than the basic HM algorithm.



[1] http://haskell.org/hoogle/
[2] http://en.wikipedia.org/wiki/Hindley-Milner

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


Re: [Haskell-cafe] Re: We tried this functional, higher-order stuff with LISP and look what happened...

2009-05-28 Thread Jason Dusek
2009/05/28 Benjamin L.Russell dekudekup...@yahoo.com:
 What makes you think that Haskell is likely eventually to dig
 a smoking hole in the ground?

  This is more about unmet expectations than spectacular
  failure.

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


Re: [Haskell-cafe] Re: Error message reform

2009-05-28 Thread wren ng thornton

Claus Reinke wrote:
Still, I would really like a just the facts, please mode for GHC, with 
less text and more type signatures (especially for the contexts of type 
mismatches). Error messages simply not including the

information I need has become my main issue with GHC messages,
and seems to be a common thread over many tickets and threads
apparently discussing phrasing (eg, expected/inferred: who expects
and why, and what is the inference based on?).


FWIW, the suggestion I floated has less text than the current message 
while preserving all the type and expression information ;)


(Though it doesn't necessarily generalize to cover similar messages like:

Prelude :t (\x - x) :: a - b
interactive:1:7:
Couldn't match expected type `b' against inferred type `a'
  `b' is a rigid type variable bound by
  the polymorphic type `forall a b. a - b' at interactive:1:0
  `a' is a rigid type variable bound by
  the polymorphic type `forall a b. a - b' at interactive:1:0
In the expression: x
)




Just, please, keep in mind that there is no one-size-fits-all:
improving a message for one group of users might well make
it less useful for another group.


+1.

There're worlds of difference between the kinds of error messages 
suitable for beginners, vs regular users, vs type-level programmers. 
Also, while a user may have some given level of understanding, the level 
of messaging they'll want can vary a lot depending on the task a hand.


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


Re: [Haskell-cafe] Problem w/YAHT code example

2009-05-28 Thread michael rice
Thanks! I just copied the code from the PDF file. Whatever that character was 
it wasn't the correct one.

Michael

--- On Thu, 5/28/09, Andrew Wagner wagner.and...@gmail.com wrote:

From: Andrew Wagner wagner.and...@gmail.com
Subject: Re: [Haskell-cafe] Problem w/YAHT code example
To: michael rice nowg...@yahoo.com
Cc: haskell-cafe@haskell.org
Date: Thursday, May 28, 2009, 10:01 PM

I'm not sure what you're using at the end of the identifier search', but it 
needs to be the single quote that's on the same key as the double quotes. I 
suspect that's where it's blowing up.


On Thu, May 28, 2009 at 9:56 PM, michael rice nowg...@yahoo.com wrote:


This code, from YAHT (Section 8.4.2, PDF pg. 119 of 192) seems to have a 
problem. Code below.

Michael

=

[mich...@localhost ~]$ ghci

GHCi, version 6.10.1: http://www.haskell.org/ghc/  :? for help

Loading package ghc-prim ... linking ... done.
Loading package integer ... linking ... done.

Loading package base ... linking ... done.
Prelude :l graph

[1 of 1] Compiling Main ( graph.hs, interpreted )


graph.hs:6:24: lexical error at character '\8217'
Failed, modules loaded: none.


==

Prelude data Graph v e = Graph [(Int,v)] [(Int,Int,e)]


search :: Graph v e - Int - Int - Maybe [Int]
search g@(Graph vl el) src dst

    | src == dst = Just [src]
    | otherwise = search’ el

    where search’ [] = Nothing
  search’ ((u,v,_):es)

  | src == u =
    case search g v dst of

  Just p - Just (u:p)
  Nothing - search’ es

  | otherwise = search’ es








  
___

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] What's the problem with iota's type signature?

2009-05-28 Thread michael rice
And I thought everyone was puzzling these type signatures out all by 
themselves. ;-)

The Haskell learning curve is about the steepest I've ever seen for a computer 
language, but I think I'm catching on.

Thanks for the info.

Michael


--- On Thu, 5/28/09, wren ng thornton w...@freegeek.org wrote:

From: wren ng thornton w...@freegeek.org
Subject: Re: [Haskell-cafe] What's the problem with iota's type signature?
To: Haskell-cafe haskell-cafe@haskell.org
Date: Thursday, May 28, 2009, 11:14 PM

michael rice wrote:
 Yeah, I went back and tried double again, though I'd swear I got the dang 
 thing to compile  (and run) w/o errors.
 
 I guess I meant Num. So Num is a class and Int and Integer are types? What 
 are the other classes? Docs?
 
 Unification, for me, is pattern matching ala Prolog. What's the meaning in 
 Haskell? Docs?
 
 I've been digging into this stuff for months and it's still tripping me up. 
 Very frustrating.


As others have mentioned, using GHCi can give you a lot of information. GHCi 
commands begin with a colon followed by the command (kinda like vi), whereas 
anything not beginning with a colon is treated as a Haskell expression to be 
evaluated. The :? command will list all the GHCi commands, which is a good 
place to start.

The :type command takes a Haskell expression and prints the type inferred for 
it. You can also use the command :set +t which will make GHCi print the type 
after evaluating each expression; you may want to use this until you get the 
hang of things. The :info command takes a whitespace separated list of 
identifiers and will print their type and other information (e.g. what module 
it comes from, what type class a function belongs to, all the functions that 
are members of a type class, fixity of operators,...)


As far as type classes and the like, there are a bunch. Hoogle[1] is an 
excellent API search engine for looking up this kind of stuff. Just enter the 
name of a function, type class, data type, or enter a type signature. The 
results give links to the online Haddock documentation (either GHC official 
docs, or Hackage docs).


Unification is used when doing type inference. It's the same unification as in 
Prolog, only at the type level. Because of the way inference works, it happens 
that the |a| and |b| type variables must be unified for both of the functions 
you gave. A whole lot more can be said here, though I'm not sure how much you 
care :)  The Wikipedia page on Hindley--Milner[2] gives a good starting point, 
though Haskell's type inference has more bells and whistles than the basic HM 
algorithm.


[1] http://haskell.org/hoogle/
[2] http://en.wikipedia.org/wiki/Hindley-Milner

-- Live well,
~wren
___
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