Re: [Haskell-cafe] US Patent for the idea of using Haskell to implement UAX #9

2010-04-17 Thread Brian Hulley

Daniel Fischer wrote:

Am Freitag 16 April 2010 20:50:25 schrieb Brian Hulley:

revealed a link to a US Patent (7120900) for the idea of implementing
the Unicode Bidirectional Algorithm (UAX #9
http://www.unicode.org/reports/tr9) in Haskell, making use, as far as I
can tell, of nothing more than the normal approach any functional
programmer would use, namely separation of concerns etc.


In which case the patent should be null and void since obvious ideas aren't 
patentable, AFAIK.

But of course, IANAL, you never know what jurists think a law means, ...


Hi Daniel,
Thanks for your reply.
The main problem for me is just the fact that the legal system in itself 
is, as Charles Dickens wrote in The Old Curiosity Shop (Chapter 37):


... an edged tool of uncertain
application, very expensive in the working,
and rather remarkable for its properties of
close shaving, than for its always shaving
the right person.

I just think somehow we should be free to write any programs we want 
just like composers can compose music, (as long as we don't just copy 
other people's actual copyrighted *code* without their permission of 
course).


After all, there is no reason why people couldn't just keep their ideas 
a secret if they don't want others to use them: at least it wouldn't 
spoil things for everyone else. Companies could even charge for *access* 
to these secrets and people could sign NDAs, but this isn't the same as 
being allowed to actually own an idea itself.


The current situation is a bit like a supermarket throwing oranges and 
apples at passers-by, then forcing people to pay if they were hit...


In any case after signing the petition I'm going to just try and forget 
about the problem! ;-)


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


Re: [Haskell-cafe] Re: US Patent for the idea ...

2010-04-17 Thread Brian Hulley

jerzy.karczmarc...@info.unicaen.fr wrote:

Brian Hulley reports a search similar to :


   haskell unicode bidirectional



Comment irrelevant to Haskell, sorry.
Everybody does his/her various jobs. But I lost all respect due to people
who work in the US Patent Office, when I saw the patent 6,025,810, a patent
for an antenna which sends signals faster than light, using some mysterious
new dimension. Or the U.S. Patent 6,960,975 for an anti-gravity device.
It seems that although it is illegal to break some local regulations, the
idea of breaking fundamental physical laws remains perfectly legal. (In
some countries...)
Somebody finally decided to ridiculise the system. If you want a good 
laugh,

see the patent 6,368,227. The search site is here:
http://patft.uspto.gov/netahtml/PTO/srchnum.htm
Best regards.
Jerzy Karczmarczuk
...


Hi Jerzy,
Yes that one is very funny.
Also the existence of the other patents just show how ridiculous the 
system is.


So thanks, that humour has helped me get back down to earth and away 
from all kinds of fruitless imaginations about the state of the world. I 
think my mind is best suited to functional programming *only*... ;-)


Cheers, Brian.

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


Re: [Haskell-cafe] Re: US Patent for the idea ...

2010-04-17 Thread Brian Hulley

Murray Gross wrote:

On Sat, 17 Apr 2010, Brian Hulley wrote:


see the patent 6,368,227. The search site is here:
http://patft.uspto.gov/netahtml/PTO/srchnum.htm
Best regards.
Jerzy Karczmarczuk
...


It's really almost not fair to cite that particular patent, since, if I
recall the story correctly (I may be wrong in small detail, but I am 
sure of the general picture), that patent was filed by an attorney as a 
demonstration to his son how the system works. It was never filed as a 
serious patent. Yes, it may show how poorly the examiners are doing 
their job, but I think this particular patent really doesn't reflect on 
the poor service we are currently receiving from the entire patent 
system--I would like to think that the examiner knew perfectly well that 
this patent was not serious and was willing to play along.


Hi Murray,
Point taken about patent 6,368,227.
I think in all fairness to examiners that in a way they have an 
impossible job due to the fact that what is a clever idea to one 
programmer will be a trivial idea to another: the field is so huge and 
people have such different experiences.


Coming back to patent 6,368,227 one could perhaps look past the humour 
and see it as a kind of indication of what the patent system is trying 
to do to humanity. I just mean to see this dispassionately as an image, 
and by trying to do I'm just anthropomorphizing what I see as a purely 
structural phenomenon that in itself is like a force of nature, that 
emerges from the inevitable incompleteness of people's understandings 
even if each person individually is trying to do what they feel is right.


In terms of a way forward for research companies I think there is a lot 
of well-paid work to be found in designing and implementing useful 
libraries of functionality, and then licensing them for inclusion in 
other programs.


After all, end users want a real implementation not just an idea, and it 
is surely much easier to trade implementations rather than to try to 
trade the rather nebulous concept of ideas.


This would allow programmers full freedom to implement whatever they 
like together with the clear advantage of being able to license well 
designed third-party libraries: we'd have total clarity and freedom.


Anyway I've said enough about software patents so I'll leave the 
discussion here and reiterate that all I want is for people to be able 
to write programs without a Sword of Damocles hanging over their heads.


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


[Haskell-cafe] US Patent for the idea of using Haskell to implement UAX #9

2010-04-16 Thread Brian Hulley

Hi everyone,
It's been a long time since I last posted to this list since I'm 
currently working on something that is not directly Haskell-related, but 
it still relates to functional programming in general.


Anyway imagine my surprise when an innocent search for some keywords (I 
can't remember the exact ones but the following gives similar results)


   haskell unicode bidirectional

revealed a link to a US Patent (7120900) for the idea of implementing 
the Unicode Bidirectional Algorithm (UAX #9 
http://www.unicode.org/reports/tr9) in Haskell, making use, as far as I 
can tell, of nothing more than the normal approach any functional 
programmer would use, namely separation of concerns etc.


The link is http://www.freepatentsonline.com/7120900.html though I think 
it would be better if they had just called the website free handcuffs 
online because that is what it amounts to when people succeed in 
preventing others from using ideas, especially ideas everyone would 
easily think up by themselves.


Before going further I would like to explicitly state that I would not 
wish to cast any aspersions upon the people or companies involved in 
this patent, since it is all too clear to me that these people have 
acted in a perfectly legal way and are just doing their various jobs: in 
other words it's an I'm a lumberjack and I'm ok... kind of scenario: 
everyone probably thinks of themsevles as being a perfectly nice 
upstanding person, and if I met any of them face to face I'm sure I 
would find that they are *indeed* really nice friendly people who 
believe that they are doing absolutely the right and logical thing.


In fact many nice people I myself have talked to about my own ideas 
immediately suggest that I should obviously patent them: it takes a 
long time to explain to them why this would not actually further my 
goals at all, and it is difficult for them to understand my explanation 
because the problem is rather too subtle for people who have not already 
been thinking along these lines for a while.


However all this does not affect the problem that this patent acts as a 
brick in the general structural evil in our world today: anyone who is 
trying to create a programming language environment that is accessible 
to people who use right-to-left languages is now between a rock and a 
hard place when it comes to implementing UAX #9, the standard Unicode 
algorithm for implementing the Unicode semantics of bidirectional text.


In this particular case, I expect (but I'm not a lawyer so please don't 
take this as solid advice: it's just a hope) that a workaround for 
Haskell programmers would be to discard their natural desire to use a 
functional approach and instead just implement UAX #9 verbatim using the 
ST monad. (The patent also tries to extend itself to other functional 
languages so caution is needed all round.)


But although the above workaround *might* be legal in this particular 
instance it seems to me that as programmers we must not just let our 
craft be dominated by the psychopathic tendencies of certain elements in 
society that work hard to try to squash the ``normals'' into a life of 
brutal misery while they rampage ruthlessly about with a biological 
inability to experience empathy for other human beings. (www.ponerology.com)


The memetic virus of psychopathy is rapidly spreading throughout human 
civilization and most people are not conscious enough of the elements 
that are contributing towards their own behaviour, thus ignoring the 
fact that the rice they eat for supper might have been picked by a tiny 
little girl in China with bleeding fingers or the carpet they walk on 
may have been made by a little 8 year old boy slave chained all day to a 
loom in a shed in India.


To this end I humbly appeal to everyone here to please help in the fight 
against software patents, so that we can begin the huge task of 
reclaiming our world for real people who understand that true meaning in 
life comes from extending our feeling of self into the world beyond our 
own body:


  http://petition.stopsoftwarepatents.eu/
  http://ffii.org

Thanks a lot for reading this,
Brian. [expecting to be crucified, but if it helps just one little girl 
or boy it will be worth it!]


Disclaimer: this email is entirely my responsibility and I am not acting 
on behalf of any of the above web sites.


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


Re: [Haskell-cafe] Looking for a more functional way to do this

2008-08-06 Thread Brian Hulley

Jefferson Heard wrote:

Adrian, my understanding is that it's not that simple, because I need
to preserve the state between calls to GLUT's callbacks, which all
return IO ().

2008/8/6 Adrian Neumann [EMAIL PROTECTED]:

There is the State Monad...




data ProgramState  = ProgramState {
   some_associative_data :: Map String String
 , position :: GL.Vector3 Float
 , look_at :: GL Vector3 Float
 , selectables :: Map GLuint NamedObject
 }

render :: IORef ProgramState - IO ()


You might find it easier to think in terms of a Reader monad where each 
component of your ProgramState above is now a separate IORef.


Then you can just use a function:

mkCallback :: ReaderT ProgramStateRefs IO () - IO ()

to create the necessary callbacks for GLUT, and there is no need to 
interleave any state between calls (since it's all kept in the IO monad 
directly).


Eg:
  data ProgramStateRefs = ProgramStateRefs
{ some_associative_data :: IORef (Map String String)
, ...
}

  main = do
r - createProgramStateRefs
let
  mkCallback :: ReaderT ProgramStateRefs IO a - IO a
  mkCallback (ReaderT r_ma) = r_ma r
GLUT.renderCallback $= mkCallback onRender
...

  onRender :: ReaderT ProgramStateRefs IO ()
  onRender = do ...

You can then go further and use phantom types to build specialized 
monads by newtyping the (ReaderT ProgramStateRefs IO) to limit the 
operations possible in each callback (e.g. to prevent calls to rendering 
methods inside a keyboard handler etc) though at some point there is a 
tradeoff between how much you really need to enforce statically and how 
much time you have to devise suitable schemes of phantom type parameters 
to enforce it.


(Disclaimer: the above code is untested and may contain errors ;-) )

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


Re: [Haskell-cafe] Capitalization and associated type families

2008-08-05 Thread Brian Hulley

Jonathan Cast wrote:


It's weird.  ML-derived languages are functional languages at the value
level (and have regular lambda-bound variables in consequence), but are
logical languages at the type level (and have logical variables in
consequence).  So ordinary lambda-bound variables, like in ML-style
functors (parametrized modules) act more like type constants than like
type variables.


Thanks - the above seems to be a promising avenue of thought to arrive 
at clarity regarding case distinctions at the type level, and I can see 
here the basis for a good argument of why there would actually be no 
inconsistency regarding the use of capitals for module type members and 
lowercase for the class parameters. Perhaps this is also the root of the 
difference between associated type synonyms and class params.


Ie at the type level, uppercase == functional variable (aka constant) 
and lowercase == logic variable...


The type level now seems to me to be quite significantly more 
complicated than the value level due to the mixing of functional and 
logic programming, not to mention that at the type level variables in 
an outer scope become constants in an inner scope as far as pattern 
matching is concerned whereas for value patterns variables are always 
fresh and never scoped (over other patterns).


Therefore I've decided to deal with the issue of case at each level 
separately since it seems immediately clear that the case distinction at 
the value level, as in Haskell/OCaml/Moby, is obviously good due to the 
foolproof nature of value patterns you pointed out, whereas at the 
type level it may also be good but I'll need a few more months to think 
about it... ;-)


Cheers,
Brian.

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


Re: [Haskell-cafe] Capitalization and associated type families

2008-08-05 Thread Brian Hulley

Tillmann Rendel wrote:

Brian Hulley wrote:


class Foo a where

f :: a - b - (a, b)

Here there is no capitalization distinction in the type of (f) but the 
implementation can still insert the forall b. since (a) is already 
in scope. Therefore similarly, if type constructors like List were 
instead written using lowercase, since they would already be in scope 
it would be clear even without explicit quantifiers that (a) and (b), 
but not (list), were to be quantified in the type of (map) (assuming 
of course that there was no top level data decl for (a) or (b)).


So adding b to the export list of an imported module would change the 
type of f?


Yes, if the module in which the above class decl were defined imported a 
data type (b) from some other module (or defined it elsewhere in the 
same module) then (f)'s type would change. (Of course at the moment this 
can't happen because (b) is lowercase so it can't be introduced by 
data/type decls or imported/exported.)


The type of (f) would also change if Haskell were extended to support 
nested classes:


class Bar b where
class Foo a where
f :: a - b - (a, b)

But as Jonathan pointed out this behaviour is not really all that ideal 
since even in Haskell at the moment a simple spelling mistake could 
cause silent quantification instead of an error (which is perhaps the 
main justification for why constructors introduced by data/type decls 
must currently be capitalized -- unfortunately there is no corresponding 
protection when writing types inside class decls):


class Zap a where
g :: a - 
^ oops!
Cheers -
Brian.
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] Capitalization and associated type families

2008-08-04 Thread Brian Hulley

Hi,
I'm familiar with the capitalization rules for identifiers in Haskell 
and know that they are very useful and practical e.g. by allowing 
variables to be distinguished from constants in patterns etc.


However I'm trying to understand on a much deeper level whether or not 
they can really be justified and indeed if there is a danger that they 
can lead to inconsistency in the light of future extensions to the language.


For example, why is there any distinction between a type variable and 
a type constant?


To make this clearer consider the type of (map):

(a - b) - List a - List b

(ignoring the special [] syntax for list types which would just confuse 
the issue here).


With explicit quantifiers, we'd write:

forall a b. (a - b) - List a - List b

Now this begs the question: why does List need to start with a 
capital? (supposing that quantifiers were always written explicitly)


The same distinction between constants and variables is also used in 
predicate logic e.g.


On(x, Table)  Colour(x, Red)

but similarly the above could surely be written just as easily by:

exists x. on(x, table)  colour(x, red)

where (on), (table), (colour), and (red) are just considered to be 
variables that have already been introduced (by some enclosing scope) 
instead of having to think of them as constants and make a distinction 
between constant and variable.


Anyway to get to the point of this post what I'm really trying to find 
is some explanation of why there is the concept of constant as opposed 
to variable or whether this concept is now redundant in the light of 
lexical scoping/ explicit quantification?


Somewhat related to this issue is the syntax of associated type 
families. For example in section 5.2.2 of 
http://www.haskell.org/haskellwiki/GHC/Indexed_types there is the example:


class C a b where
data T a

which raises in my mind several questions:

1) Why is (T) given a parameter? I.e. why does an associated type 
declared inside a class decl not automatically get all the parameters of 
the class passed to it so that one would just write:


class C a b where
data T
f :: T - T
===
data family T a b
class C a b where ...
f :: T a b - T a b

2) Compare:

class C a b t | a b - t
with
class C a b where
data T

In other words, why is (T) a constant when it is declared inside the 
class but a variable when passed as a parameter?


Is the fact that (T) needs to be given a parameter even when it is 
declared inside the scope of the class type parameters the result of 
needing to fulfill the idea of constant vs variable?


3) In the syntax:

class C a b
data T a

it seems rather odd that the a in T a should be related to the a 
in C a b since one might expect that the name chosen for a parameter 
should be local to the data decl.


Apologies for such a rambling post. I've spent literally at least 6 
months scouring the internet trying to find a real discussion about 
capitalization rules because I'm trying to answer the following 
question: if I make use of a similar capitalization rule in my own 
language, can I guarantee that this rule will not lead to an 
inconsistency at some future point? Ie is there a real rock solid 
theoretical basis for making a distinction between constants and 
variables that holds even in the presence of lexical scoping?


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


Re: [Haskell-cafe] Capitalization and associated type families

2008-08-04 Thread Brian Hulley

Jonathan Cast wrote:

On Mon, 2008-08-04 at 19:51 +0100, Brian Hulley wrote:
For example, why is there any distinction between a type variable and 
a type constant?


forall a b. (a - b) - List a - List b

Now this begs the question: why does List need to start with a 
capital? (supposing that quantifiers were always written explicitly)


AFAIK, it doesn't; the variable/constant distinction is just there to
let the implementation put the foralls in for you.


Hi Jonathan - thanks - this confirms what I've been thinking. However 
consider:


class Foo a where

f :: a - b - (a, b)

Here there is no capitalization distinction in the type of (f) but the 
implementation can still insert the forall b. since (a) is already in 
scope. Therefore similarly, if type constructors like List were 
instead written using lowercase, since they would already be in scope it 
would be clear even without explicit quantifiers that (a) and (b), but 
not (list), were to be quantified in the type of (map) (assuming of 
course that there was no top level data decl for (a) or (b)).



 Similarly, if we had
explicit foralls on equations, we could say

forall n x xn. drop (n+1) (x:xn) = drop n xn

but

forall n. drop n nil = nil

and it would be perfectly clear that `nil' in the latter case was a
constructor.


Actually I quite like the above because it shows that pattern matching 
can be understood in terms of universally quantified predicates.


Regarding the verbosity, patterns are something of a special case since 
variables (that are introduced in the pattern) can only occur once and 
there is no need to have higher rank quantification in value patterns 
(disregarding explicit tests for _|_). Therefore special syntax could be 
used to make the above shorter e.g. borrowing the '?' from Felix 
(http://felix.sourceforge.net/doc/tutorial/introduction/en_flx_tutorial_top.html 
 (section 2.11/2.17 etc)):


drop (?n + 1) (_ : ?xn) = drop n xn
drop ?n nil = nil

(where glued prefix binds tighter than application).



Of course, if you want to introduce this rule, you'd better start out
with it and be consistent --- require every variable to be explicitly
brought into scope.  I think you'd find it pretty annoying after trying
to program in your new language for a while, though.



I agree that there are many good points in favour of Haskell's use of a 
case distinction, not the least being that it gives definite guidance on 
when to use lower or upper case identifiers and therefore avoids the 
mess you find in C++ programs where every programmer has their own 
private conventions which can lead to confusion and useless debate.


However it still seems to me that the case distinction, at least on the 
level of type constructors, becomes problematic and possibly 
inconsistent especially if I consider the effects of trying to 
incorporate something like the ML module system as well as type classes. 
(For example the Moby language (http://moby.cs.uchicago.edu/ ), a 
possible successor to SML, uses capitalization for type constructors 
similar to Haskell which means that type parameters in functor 
applications must be uppercase, which conflicts with the use of 
lowercase type params for classes which are a special kind of functor... 
(Moby itself doesn't encounter any difficulty since it doesn't have type 
classes)).


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


Re: [Haskell-cafe] Dynamic choice of reverse implementation

2007-09-28 Thread Brian Hulley

Krzysztof Kościuszkiewicz wrote:

Fellow Haskellers,

I wanted to experiment a bit with lists and sequences (as in Data.List and
Data.Sequence), and I got stuck. I wanted to dynamically select processing
function depending on cmdline argument:

  

main = do
args - getArgs
let reversor = case args of
[sequence] - reverseList
[list] - reverseSeq
_ - error bad args
input - getContents
let output = reversor $ lines $ input
mapM_ putStrLn output



In my oppinion reversor would have type

  

reversor :: (Foldable f) = [a] - f b



  


No, this is the wrong type. To find the correct type, if you look at the 
type of the input argument in your code it will be the result of 
(lines), so from ghci:


Prelude :t lines
lines :: String - [String]
Prelude

Therefore (reverseor) has type [String] - ???
Now for the output type, you are using (output) as an input to (mapM_ 
putStrLn). (mapM_) takes a list and uses its argument to do something to 
each element of the list. So, since the input to (putStrLn) is (String), 
the input to (mapM_ putStrLn) is ([String]).

Therefore

   reversor :: [String] - [String]

So reverseList is just Data.List.reverse as you've got it (though 
presumably you meant to write [list] - reverseList and not reverseSeq).


For using Data.Sequence to implement reversor, all you need to do is 
first convert [String] to Seq String, reverse the sequence, then convert 
back from Seq String to [String].


Hope this helps,
Brian.



but I couldn't get this to work. I've tried typeclass approach:

  

class (Foldable f) = Reversor f where
reverse' :: [a] - f a

instance Reversor ([]) where
reverse' = Data.List.reverse

instance Reversor ViewR where
reverse' = viewr . foldr (|) empty 


reverseList = reverse' :: (???)
reverseSeq  = reverse' :: (???)



but now in order to differentiate between reverse' functions I'd
have to provide different type annotations, and then reversor won't
typecheck...

Similar problem surfaced with this try:

  

data Proc = SP | LP
reverseList = reverse' LP
reverseSeq = reverse' SP

reverse' :: (Foldable f) = Proc - [a] - f a
reverse' LP = Data.List.reverse
reverse' SP = viewr . foldr (|) empty



So now I'm looking for some suggestions how should I approach the
problem...

Regards,
  

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


Re: [Haskell-cafe] Dynamic choice of reverse implementation

2007-09-28 Thread Brian Hulley

Brian Hulley wrote:

Krzysztof Kościuszkiewicz wrote:

So the type of mapM_ used in the code is
(Foldable t, Monad m) = (a - m b) - t a - m ()

I'd like to keep the generic Foldable t there when m is specialized 
to IO.

I thought this would allow type of reversor to be specialized to
(Foldable f) = [String] - f String
  ... I'd like to avoid [a] - something - [a]


Yes this type should be fine.


I should have said though that in your code, because one arm of the case 
construct returns Data.List.reverse, the type of reversor is fixed to 
[a] - [a].


The other arm of the case construct could make use of a more general 
function eg


   reverseFoldable :: (Foldable f, Foldable g) = f a - g a

but it would only be used at f == [], g == [].

So in terms of the command line test harness, I think the only way is to 
explicitly choose the foldable you want to try out eg by using 
(Foldable.toList . Seq.reverse . Seq.fromList) etc.


An alternative might be to just write some different implementations of 
reverse functions in a module then load the module into ghci to test 
them out interactively so their types don't get unified with each other.


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


Re: [Haskell-cafe] Dynamic choice of reverse implementation

2007-09-28 Thread Brian Hulley

Krzysztof Kościuszkiewicz wrote:

So the type of mapM_ used in the code is
(Foldable t, Monad m) = (a - m b) - t a - m ()

I'd like to keep the generic Foldable t there when m is specialized to IO.
I thought this would allow type of reversor to be specialized to
(Foldable f) = [String] - f String
  
... I'd like to avoid [a] - something - [a]


Yes this type should be fine. To implement reversor though you'd still 
need to first convert from the concrete list to whatever foldable you're 
using, before reversing the foldable, or implement something more 
general eg:


reversor :: (Foldable f, Foldable g) :: f a - g a

Of course with lazy evaluation + compiler optimizations the lists in [a] 
- something - [a] should be erased at compile time... ;-)


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


Re: [Haskell-cafe] Desugaring of infix operators is (always?) the wrong way round

2007-09-27 Thread Brian Hulley

Sam Hughes wrote:

Brian Hulley wrote:

... For example, with the prefix definition of a function with 
multiple clauses, the function name at the start of each clause is 
already lined up since it must appear at the margin of the current 
layout block ...


Or you could have everything be backwards, and use an editor that 
right aligns things.



   (a - b) - [a] - [b] ::  map
[] = [] _ map
x f : xs f map = (x:xs) f map



There is still a reversal here between the order of arguments in the 
type signature and the order in the clauses.


Henning Thielemann wrote:



Curried functions like

f :: a - b - c

suggest a swapped order of arguments for (-), since 'f' must be 
called this way


b a f

Maybe it should be

f :: c - b - a




Which would fix this reversal. However there are 2 other kinds of 
reversal with postfix notation:
1) Declarations start with a keyword followed by some content whereas 
function definitions start with the args followed by the function name
2) Special constructs like case or let have to start with the 
keyword (so the parser knows what kind of thing it is supposed to parse 
next and so that the editor knows how to highlight what the user is 
typing before the user has finished typing the whole construct), again 
making a reversal between built-in constructs and constructs you can 
define using higher order functions (eg consider if as a user-defined 
construct in a postfix language)


I've come to the conclusion that whereas postfix notation is extremely 
neat for simple stack-based languages like Forth and PostScript it would 
not play well with languages which have a structured syntax since 
structured syntax + left to right reading order implies each syntactic 
element must start with a head followed by content appropriate to that 
element, or else recursive descent parsing and/or as-you-type 
grammatical highlighting would be impossible, and therefore in terms of 
function application, the head must of course be the function itself 
hence Prefix is the only solution.


Jonathan's comparison to natural languages made me think of it this way:

   x `plus` y   ===  [Subject] [Verb] [Object]

   x .plus(y) === [Subject] [Verb Object]

   plus y x === [Verb Object] [Subject]

   plus x y === [Verb Subject] [Object]

which illustrates why infix notation feels natural (corresponds to SVO 
in English etc), why OOP notation feels natural, why prefix notation is 
natural for a functional language (since we are interested primarily in 
the transformation not the things being transformed hence we put [VO] 
first), and why the desuraging of infix in Haskell/ML is quite simply 
just wrong, since the object is now separated from the verb.


ok wrote:

Binary operators have two arguments.  That's why sections are needed.


What's wrong with just using (flip)?




I am a bear of very little brain, and I would find it VERY confusing
if the order of arguments in an operator application did not match
the order of arguments in a function call.  I can live with
x @ y = (op @)(x, y)(* SML *)
x @ y = (@) x y-- Haskell
but making the orders different would guarantee that I would *always*
be in a muddle about which argument was which.  Living with
inconvenient argument orders is vastly easier than with inconsistent 
ones.


If you inwardly parse x @ y as [x] [@ y] then the prefix notation is 
naturally formed just by putting the specialized verb before the 
subject instead of after it ie [@ y] [x].
Therefore I think this desugaring, though different from the usual one, 
would seem natural as soon as the reason for it was understood (of 
course, only if you agree with the reason ;-) ), and the great advantage 
of it is that we could write library functions without having to decide 
in advance whether or not they should be used with infix sugar.


(Regarding Henning's point about ((-) a) being needed for Reader monads 
we could define type Fun a b = a - b and then use (Fun a))


In any case, thanks to all who replied. I've found the discussion very 
illuminating and it's certainly helped a lot to clarify the issues for me,


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


[Haskell-cafe] Desugaring of infix operators is (always?) the wrong way round

2007-09-25 Thread Brian Hulley

Hi,

I'm in the process of designing a little language inspired by Haskell 
but imperative, and have hit an issue regarding infix syntax which may 
be of interest also to anyone thinking about future revisions of Haskell 
or the problem of consistent parameter order in libraries.


I'm wondering if anyone can shed light on the reason why

   x # y

gets desugared to

  (#) x y

and not

  (#) y x

since the first desugaring always seems to lead to (#) having to be 
defined in a way that is unnatural for functional programming. This is 
why a lot of functions in the standard libraries have their arguments 
the wrong way round. For example in Data.Bits we have:


   shiftL :: a - Int - a

whereas the natural argument order for a functional language would be to 
make it so that in an application one has the verb first followed by the 
noun as in:


   shiftL' :: Int - a - a

so we could write (shiftL' 3) to denote the operation of shifting 
something left by 3 eg:


  let
   shiftLeftByThree = shiftL' 3
  in
  map shiftLeftByThree  [10, 78, 99, 102]

(This choice of argument order is explained at 
http://www.haskell.org/haskellwiki/Parameter_order )


Similarly, considering arithmetic, it would make a lot more sense to me 
to define:


   x - y === (-) y x

since the action here is take away y and the noun is x so the 
natural functional reading of (-) a b is subtract a from b.


To be consistent this would also have to apply to the use of (-) in 
types to get:


   a - b === (-) b a

Can anyone think of an example where the current desugaring of infix 
arguments gives the correct order when the function is used in a postfix 
application? (apart from commutative functions of course!)


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


Re: [Haskell-cafe] Desugaring of infix operators is (always?) the wrong way round

2007-09-25 Thread Brian Hulley

Brian Hulley wrote:

I'm wondering if anyone can shed light on the reason why

   x # y

gets desugared to

  (#) x y

and not

  (#) y x



Can anyone think of an example where the current desugaring of infix 
arguments gives the correct order when the function is used in a 
postfix application? (apart from commutative functions of course!)



Sorry I meant to write *prefix* application
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Desugaring of infix operators is (always?) the wrong way round

2007-09-25 Thread Brian Hulley

Jonathan Cast wrote:

On Tue, 2007-09-25 at 19:18 +0100, Brian Hulley wrote:
  

Brian Hulley wrote:


I'm wondering if anyone can shed light on the reason why

   x # y

gets desugared to

  (#) x y

and not

  (#) y x

  

Of course, this is all a consequence of the well-known failure of
natural language: verbs come before their objects.  It is thus natural
to write f(x), when in fact it is the object that should come first, not
the function.  Switching to a (natural) language where (finite) verbs
come at the end of sentences, where they belong, should fix this issue
in time.  Doing the same in a functional language would be ideal as
well, but might limit its use among those who speak inferior natural
languages.
  
Thanks, I must look into using postfix notation. It's used in Forth and 
Postscript and I seem to dimly recall that there is a natural language 
somewhere that also uses it but I can't remember which one.


Not only would it solve the infix/prefix dilemma, but it would also be 
consistent with a sugar for an object oriented syntax for application:


   a b c f
   a .f(b, c)

(Using a dot glued on its right and a left paren glued left to avoid 
ambiguity with unglued dot (function composition) and unglued left paren 
(unit/tuple/bracketing))


It's not so clear to me what the syntax for types should be in a postfix 
language.
Also, a problem might be that it is not so easy to use the 
multiple-clause style of function definition eg compare:


   map _ [] = []
   map f (h : t) = f h : map f t

with

   [] f map = []
   (h : t) f map = h f : t f map

since the function name is no longer conveniently at the margin of 
whatever layout block we are in so extra efforts would need to be made 
to line them up, though this is a minor issue.


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


Re: [Haskell-cafe] Desugaring of infix operators is (always?) the wrong way round

2007-09-25 Thread Brian Hulley

Ryan Ingram wrote:

My comments inlined below...

On 9/25/07, Brian Hulley [EMAIL PROTECTED] wrote:
  

  let
   shiftLeftByThree = shiftL' 3
  in
  map shiftLeftByThree  [10, 78, 99, 102]



let shiftLeftByThree = (`shiftL` 3) in ...

  
Aha! but this is using section syntax which is yet another complication. 
Hypothesis: section syntax would not be needed if the desugaring order 
was reversed.

Can anyone think of an example where the current desugaring of infix
arguments gives the correct order when the function is used in a postfix
application? (apart from commutative functions of course!)



A couple off the top of my head:

(:) :: a - [a] - [a]
  


Yes that's one that had totally slipped my mind ;-)

| :: MonadPlus m = m a - m a - m a
(how do you define correct in this case, anyways?)
  


I'm not so sure about this one eg:

first | second
(trychoice second) first

because (trychoice second) encapsulates what to do when its argument 
action fails.

Even for shift I can think of several reasons to want to use it both
ways; for example, unpacking a bitfield from a Word16:

unpack v = (getM 0 255, getM 8 1, getM 9 31, getM 14 3)
where getM = (..) . (shiftR v)

  
I suppose with some ops perhaps there is no most common way of wanting 
to use them and hence no one-true-way argument order for those ops.


Thanks for the examples,
Brian.
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Desugaring of infix operators is (always?) the wrong way round

2007-09-25 Thread Brian Hulley

Dan Piponi wrote:

On 9/25/07, Brian Hulley [EMAIL PROTECTED] wrote:

..I seem to dimly recall that there is a natural language
somewhere that also uses it but I can't remember which one.



Every permutation of [S,V,O] appears in 'nature':
http://en.wikipedia.org/wiki/Word_order.
  


Thanks for the link - I see [Subject, Object, Verb] is actually the most 
common word order.
  
Also, a problem might be that it is not so easy to use the 
multiple-clause style of function definition 


I disagree, it's easier with postfix functions. With prefix functions,
to get line-up you insert space in the middle of the line. With
postfix notation you would often insert space at the beginning of a
line, a much easier place to insert text, because there is a
keystroke, in most text editors, to take you to the beginning of a
line.

  


I don't understand what you mean. For example, with the prefix 
definition of a function with multiple clauses, the function name at the 
start of each clause is already lined up since it must appear at the 
margin of the current layout block (especially if you follow the simple 
rule of always following a layout starter token by a newline rather than 
starting a new multi-line layout block in the middle of a line), whereas 
with the postfix notation you'd need to manually line up the function 
names if you wanted the same neat look.



It's not so clear to me what the syntax for types should be in a postfix 
language.



Postfix, of course! So you'd write

data a Tree = Leaf | a a Tree
  


Sorry I meant what should the syntax of type declarations for functions 
be? For example, with prefix map (writing lists without sugar for 
clarity) we have:


   map :: (a - b) - List a - List b
   map _ Empty = Empty
   map f (PushF h t) = PushF (f h) (map f t)

The occurrence of map in the type decl lines up with the 2 occurrences 
of map in the clauses, and the types of the arguments are in the same 
order in the type as in the patterns in the clauses.


A postfix version could be:

   map :: (a - b) - a List - b List
   Empty _ map = Empty
   (h t PushF) f map = (h f) (t f map) PushF

but now the occurrences of map no longer line up and the argument 
order is reversed between the type and the value syntax.


Of course the problem disappears if you just discard multiple clause 
syntax and use:


  (list :: a List) (f :: a - b) map :: b List =
   case list of
   Empty - Empty
   h t PushF - (h f) (t f map) PushF


Confusingly, ocaml does something like this, with postfix notation for
types and prefix notation for function application.


I've never understood why {Oca, S}ML's creators decided to make life so 
difficult and confusing by introducing an arbitrary reversal between 
type and value syntax. ;-)


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


[Haskell-cafe] Syntax for lambda case proposal could be \of

2007-08-15 Thread Brian Hulley

Hi,
On http://hackage.haskell.org/trac/haskell-prime/wiki/LambdaCase the 
proposed syntax for lambda case is:


   case of
   alts

but this has a really bad downside for interactive editors: it doesn't 
allow one to distinguish between an incomplete construct and a completed 
construct thus removing one opportunity for an editor to alert the user 
(eg by highlighting) that there is something missing in the program text.


Therefore I propose:

   \of
   alts

which doesn't suffer this problem since the keyword of can never 
follow a '\' in the existing grammar.


However I can't edit the H' wiki, so if anyone agrees that the above 
syntax is better please could they add the above to the page.


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


Re: [Haskell-cafe] Syntax for lambda case proposal could be \of

2007-08-15 Thread Brian Hulley

Stefan O'Rear wrote:

On Wed, Aug 15, 2007 at 06:58:40PM +0100, Duncan Coutts wrote:
  

On Wed, 2007-08-15 at 10:50 -0700, Stefan O'Rear wrote:



OTOH, your proposal provides (IMO) much more natural syntax for
multi-pattern anonymous functions, especially if we stipulate that
unlike a case (but like a lambda) you can have multiple arguments; then
you could write stuff like:

sumTo0 = foldr (\of 0 k - 0
n k - n + k) 0
  

sumTo0 = foldr (\0 k - 0
 n k - n + k) 0



foo = getSomethingCPS $ \ arg -
  moreStuff

is now a syntax error (\ { varid - } matches no productions).
  

A multi-way lambda could be introduced using \\ thus:

sumTo0 = foldr (\\ 0 k - 0; n k - n + k) 0

[from a previous post]

It's not like the current language has that property; consider (map
myFunction) - is that an error or a partial application?


By construct I meant only those grammatical elements involving keywords, and 
was thinking about situations where you might for example have various syntax templates 
bound to function keys eg in Haskell the following are incomplete:

  case of
  if then else
  data where deriving

(let in could still be marked as incomplete even if it is ok according to the 
grammar since it would be weird to bother writing a let with no bindings.)

There is a similar problem with the way template haskell uses unmatched quotes 
such as 'a so it's no longer possible to determine whether this should be 
marked as an incomplete character literal or a complete TH name.

I suppose my main point is that it's useful for a syntax to have plenty of unfilled 
gaps that result in an error when written rather than filling all those gaps with 
different meanings...

Brian.

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


Re: [Haskell-cafe] Re: Language support for imperative code. Was: Re: monad subexpressions

2007-08-13 Thread Brian Hulley

Brian Hulley wrote:

apfelmus wrote:

Brian Hulley schrieb:

   main = do
   buffer - createBuffer
   edit1 - createEdit buffer
   edit2 - createEdit buffer
   splitter - createSplitter (wrapWidget edit1) (wrapWidget 
edit2)

   runMessageLoopWith splitter

... Thus the ability to abstract mutable state gives to my mind by 
far the best solution.


I'm not sure whether mutable state is the real goodie here. I think 
it's the ability to indpendently access parts of a compound state.

  http://www.st.cs.ru.nl/papers/2005/eves2005-FFormsIFL04.pdf


This is indeed a real key to the problem.

Of course this is only one aspect of the problem...

Thinking about this a bit more, and just so this thought is recorded for 
posterity (!) and for the benefit of anyone now or in a few hundred 
years time, trying to solve Fermat's last GUI, the object oriented 
solution allows the buffer object to do anything it wants, so that it 
could negotiate a network connection and implement the interface based 
on a shared network buffer for example, without needing any changes to 
the client code above, so a functional gui would need to have the same 
flexibility to compete with the OO solution.


Another thing that would be interesting would be to have a formal 
treatment of what is supposed to happen in a gui. For example, when you 
move the mouse over a control which has become dirty (ie needs to be 
re-rendered because its state is now inconsistent), what should the 
control do? Should it respond as if the new state were already visible 
to the user, or should it interpret the mouse position according to the 
last state that was rendered, or should it just ignore all mouse events 
until the next time it gets rendered? This is not a trivial question 
because you could imagine an animated control where the user might 
naturally be following the movement, whereas when the user clicks on a 
cell in a spreadsheet when the cells to the left have now expanded due 
to a change in data thus moving the cell along (but where this updated 
model has not yet been re-rendered) the user might be irritated at the 
wrong cell being selected... It's tricky little issues like this that I 
haven't found any documentation for anywhere, and which would make a 
proper mathematical treatment of interaction with a gui very useful, 
regardless of whether it is implemented in OOP or functional style.


Anyway just a thought,

Brian.


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


Re: [Haskell-cafe] Re: Language support for imperative code. Was: Re: monad subexpressions

2007-08-12 Thread Brian Hulley

apfelmus wrote:

Brian Hulley schrieb:

   main = do
   buffer - createBuffer
   edit1 - createEdit buffer
   edit2 - createEdit buffer
   splitter - createSplitter (wrapWidget edit1) (wrapWidget 
edit2)

   runMessageLoopWith splitter

... Thus the ability to abstract mutable state gives to my mind by 
far the best solution.


I'm not sure whether mutable state is the real goodie here. I think 
it's the ability to indpendently access parts of a compound state. In 
other words, the IORef created by  buffer  is a part of the total 
program state but you can access it independently. There is a 
functional idiom for that, see also


  Sander Evers, Peter Achten, and Jan Kuper. A Functional Programming
  Technique for Forms in Graphical User Interfaces.
  http://www.st.cs.ru.nl/papers/2005/eves2005-FFormsIFL04.pdf


Thanks for this reference. This is indeed a real key to the problem. 
(Though a possible downside with compositional references might be 
efficiency as the modified sub-state needs to be injected back into a 
new composite state but perhaps the solution here would be to have 
uniqueness typing as in Clean so that these injections could hopefully 
be erased at compile time.)


I think one of the issues with Haskell is that there are so many 
features to choose from it is difficult to know how to approach a 
problem eg for streams you can have


1) A lazy list
2) A typeclass with get and pushBack methods
3) An object using an existential to wrap (2)
4) A record containing get and pushBack methods
5) A monad with get and pushBack actions
6) A simple function wrapped in a newtype:

 newtype Stream a = Stream (() - Maybe (a, Stream a))

and I tend to only discover a simple solution like (6) (which works 
equally well for both strict and lazy languages) after spending an 
enormous amount of time on 1,2,3,4,5... ;-)


- For Graphics, I want to build a graphic from smaller ones and then 
draw it. I don't want to know how drawing is implemented and what 
mutable state might be involved.
- For a GUI, I want to write down the data dependencies and a library 
converts this to a mesh of mutable state.


That's what I mean with higher level functional model.
I agree this would be ideal. A challenge I don't yet know how to solve, 
when dealing with 3d graphics, is that it seems that for efficiency it 
is necessary to consider a mesh of triangles to be an object with 
identity in order to be able to display an updated mesh (eg as the user 
drags a vertex with the mouse) in real time. This is because the 
representation of a mesh is constrained by the low level details of the 
graphics system eg vertices might need to be represented by a contiguous 
array of unboxed positions and normals, and triangles by a contiguous 
array of vertex indices, and it is too expensive to copy these arrays on 
each frame. Perhaps though this is another case where some form of 
uniqueness typing as in Clean could come to the rescue so one could write:


   createMesh :: [Vertex] - [[VertIndex]] - Mesh
   moveVertex :: Vertex - *Mesh - *Mesh

instead of

   createMesh :: [Vertex] - [[VertIndex]] - IO Mesh
   moveVertex :: Vertex - Mesh - IO ()

Best regards, Brian.

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


[Haskell-cafe] Language support for imperative code. Was: Re: monad subexpressions

2007-08-08 Thread Brian Hulley

apfelmus wrote:

However, most genuinely imperative things are often just a building
block for a higher level functional model. The ByteString library is a
good example: the interface is purely functional, the internals are
explicit memory control. It's a bad idea to let the internal memory
control leak out and pollute an otherwise purely functional program with
IO-types.
  

Hi Apfelmus,

This is a really interesting discussion that touches on issues I'm 
currently working with (I'm designing a strict version of Haskell to 
explore various ideas about modules, namespace management, and how to 
get really efficient machine code but without losing the convenience of 
accurate garbage collection etc, but I'm having difficulties deciding 
between the monadic path and the impure path), so I've forked this new 
thread.


Regarding the quote above, if the API must hide explicit memory control 
from the user the only way I can see of doing this would be to use 
(unsafePerformIO), which really is unsafe since Haskell relies on the 
fact that mutable operations can't escape from the IO monad in order to 
get away with not having to impose a value restriction as in ML.


If you don't use (unsafePerformIO), then the slightest need for mutable 
data structures pollutes the entire interface. For example in the 
excellent paper you quoted


 N. Ramsey and J. Dias.
 An Applicative Control-Flow Graph Based on Huet's Zipper
 http://www.eecs.harvard.edu/~nr/pubs/zipcfg-abstract.html 
http://www.eecs.harvard.edu/%7Enr/pubs/zipcfg-abstract.html


the authors are pleased to have found an Applicative solution, and 
indeed their solution has many useful and instructive aspects. However 
on page 111, hidden away in the definition of their API function to 
create a label, is a call to (ref 0)  ;-) The equivalent 
implementation in Haskell would completely destroy all hope of using 
this in a pure context and force all use of the API into the IO monad.


Haskell and ML seem to stand at opposite poles. Haskell is designed so 
that any attempt at abstracting mutable local state will infect the 
entire program (modulo use of a highly dangerous function whose 
semantics is entirely unclear, depending on the vagaries of evaluation 
strategy of the particular compiler) whereas people have been struggling 
in the ML community for at least 15 years to try and find a way to hide 
the fact that mutable storage is being used (cf attempts to find a 
proper solution to the unsoundness introduced by polymorphism and ref 
without having to use imperative/weak type variables etc).


Meanwhile, C++, C#, and Java programmers get a type system (thinking 
only about static methods using generics/templates) that seems to me no 
less powerful than that of the prenex polymorphism of ML, yet without 
any of the unsoundness problems, and therefore without the need of a 
value restriction (afaiu this is because their template/generic 
definitions stand in for an infinite family of monomorphic bindings 
instead of ML which tries unsuccessfully to make one piece of memory 
represent each element of an infinite family of values simultaneously).


Not only this, but there seems to me to be many problems for which it is 
natural to think in terms of objects with identity and mutable state. I 
can readily discard the concepts of deep inheritance hierarchies and 
open recursion but this still leaves the problem of identity and 
localised mutability.


For example consider a simple GUI with 2 edit widgets, a splitter, and a 
single buffer that contains the text being edited. The idea is that you 
should be able to use either edit widget to interact with the same 
buffer eg to edit at different locations in the buffer. A simple 
imperative solution might be something like:


   main = do
   buffer - createBuffer
   edit1 - createEdit buffer
   edit2 - createEdit buffer
   splitter - createSplitter (wrapWidget edit1) (wrapWidget edit2)
   runMessageLoopWith splitter

Here it's really clear what's happening, and different objects in the 
program correspond exactly to how I think about what I'm trying to do ie 
I want to  create individual objects with identity and then plug them 
together. I don't want to have to bother about passing state around, or 
having to define a new data type every time I want a different 
configuration of widgets. Thus the ability to abstract mutable state 
gives to my mind by far the best solution.


In contrast, all the pure functional GUIs that I've seen are just 
wrappers around someone else's imperative code, and moreover, they 
exchange the simplicity of the object oriented imperative API for a 
veritable mindstorm of unbelievably heavy, clunky, slow, inefficient, 
inextensible, hard to understand encodings that seem to me to have the 
effect of turning a high level language into some kind of circuit board 
(I'm thinking of arrows etc).


Indeed everyone seems to be using either WxWidgets or 

Re: [Haskell-cafe] Language support for imperative code. Was: Re: monad subexpressions

2007-08-08 Thread Brian Hulley

Martin Percossi wrote:

Brian Hulley wrote:

hidden away in the definition of their API function to create a 
label, is a call to (ref 0)  ;-) The equivalent implementation in 
Haskell would completely destroy all hope of using this in a pure 
context and force all use of the API into the IO monad.


Really? I would have thought this is a job for the ST monad, in which 
case the API can be wrapped up in a runST or similar; no need for 
leaking IO monads.


Or am I missing something?


Well I agree you're right on this particular use of a Ref, since their 
program is only dealing with a mapping from input to output so once 
they're finished using the data structure there is no longer any need 
for the ref and so the result can be returned to the rest of the program.


However there are 2 problems with this approach in general afaics:

1) All code that uses this data structure ie that participates in the 
implementation of the transformations by using the API functions will 
have to be in a monad (ST or IO, it really doesn't matter in terms of 
all the perceived burdensomeness of do notation relative to normal 
applicative code).


2) The example doesn't transfer to an interactive situation, where we 
would need to keep the data structure around and use it forever - 
because we would be forever trapped inside the ST monad otherwise we'd 
lose that particular STRef which we were hoping to use to efficiently 
update the output in the face of a delta in the input.




Corey -
I found this page helpful to get an understanding of the value 
restriction in ML:


http://www.smlnj.org/doc/Conversion/types.html

The restriction was proposed by Andrew Wright in 1995:

Simple Imperative Polymorphism by Wright
http://citeseer.ist.psu.edu/wright95simple.html

Some other related papers are:

The Type and effect discipline by Talpin and Jouvelot 1992
Standard ML-NJ weak polymorphism and imperative constructs by Hoang, 
Mitchell, and Viswanathan

Weak polymorphism can be sound by Greiner 1993

and more recently (2003)

Relaxing the value restriction by Garrigue
http://citeseer.ist.psu.edu/garrigue03relaxing.html

(Note that even now there is still no real solution to it.)


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


Re: [Haskell-cafe] Language support for imperative code. Was: Re: monad subexpressions

2007-08-08 Thread Brian Hulley

Hugh Perkins wrote:
On 8/8/07, *Brian Hulley* [EMAIL PROTECTED] 
mailto:[EMAIL PROTECTED] wrote:


In contrast, all the pure functional GUIs that I've seen...

In defense of Haskell (wow!), note that imperative languages are not 
without problems in GUIs.  In a multithreaded environment,
If you're using multiple threads you'd need to be in the IO monad to 
create/manipulate the MVars or TVars or whatever. (In contrast to eg 
AliceML where you could easily use a synchronising logic variable 
without having to leave all the familiar applicative coding comforts 
behind to brave the fiercesome lonely toil of Monadia ;-))


typically only one thread is allowed to manage the GUI, and then you 
typically need to set up some sort of message-passing system to 
communicate between this thread and the others AFAIK?  This is a total 
PITA, so if someone has a solution for this that would rock :-)
 
Question: to what extent do the Haskell wrappers around gtk and 
wxWidgets suffer from this problem?  I mean, I havent tried them, so 
it's a genuine question.
I don't know though I seem to recall some info on this on the website of 
Gtk2Hs.


 
(Note: off the top of my head, in an imperative language, I guess one 
could use some sort of generator to take an interface and generate the 
message classes, and marshalling classes automatically)
 
(Disclaimer: I havent really searched very hard for ways to handle 
threading in GUIs in imperative languages, since mostly I either use 
web pages as the visual interface, which avoids around the problem, or 
use a single thread, which also avoids the problem)


So far I've always managed to get away with just using a single threaded 
GUI. I think you run into problems with XLib and OpenGL (on GNU/Linux at 
least) if you try to call into those APIs from multiple threads and also 
it seems better to separate concerns by having all rendering code, 
including cacheing of geometry etc, in the same thread since it's easy 
enough to spawn new threads to do calculations and set a flag in the 
relevant widget when the result is complete...


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


Re: [Haskell-cafe] a regressive view of support for imperative programming in Haskell

2007-08-08 Thread Brian Hulley

Paul Hudak wrote:
All of the recent talk of support for imperative programming in 
Haskell makes me really nervous


... if we give imperative programmers the tools to do all the things 
they are used to doing in C++, then we will be depriving them of the 
joys of programming in the Functional Way.  How many times have we 
seen responses to newbie posts along the lines of, That's how you'd 
do it in C++, but in Haskell here's a better way
Perhaps I may have sounded unappreciative of all the hard work that's 
been done trying to find solutions to the problem of GUI programming in 
a pure functional style. I think the problem is that for the purposes of 
research, it is sufficient to show that a concept can be implemented but 
the speed of the resulting program is not that important compared to the 
essential ideas.


Thus the concept of a GUI as a time varying continuous function of 
events and response pictures (represented as functions:: Vector3 Float 
- RGB) is tremendously appealing, and will surely become the standard 
way when machines get fast enough, but for the moment this nice pure 
functional way just doesn't seem directly applicable (;-)).


I see the problem you're pointing to though - that the language could 
become caught in the middle trying to serve two rather different 
purposes namely a pure ground for research and a fast general purpose 
platform for creating programs now. As for me, the issue is just that 
after spending almost 2 years with Haskell trying to find/discover a 
purely functional solution to this problem that will be suitable for a 
practical high speed graphics application on standard hardware, being 
unsuccessful, and not having any funding to pursue this research 
further, my only option is to either use the imperative monadic style of 
Haskell programming or to use OCaml or C++, because I need to get 
something written right now that I can put on my website to sell...


Personally I don't find the existing do notation all that burdensome - 
I've got used to it, and even though each action must be explicitly 
written, the ease with which higher order functions can be introduced to 
factor out commonality means that the do blocks are often shorter than 
the corresponding C++ code from my previous GUI.


Furthermore, even though I'm using the imperative style, the use of 
Haskell has led me to surprisingly neat solutions to several problems 
that I didn't discover when I implemented the previous versions in C++ 
and C#, so I think there are still great benefits to be had from using 
Haskell or languages inspired by it.


Best regards, Brian.





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


Re: [Haskell-cafe] Newbie question: multi-methods in Haskell

2007-08-06 Thread Brian Hulley

peterv wrote:

In de book Modern C++ design, Andrei Alexandrescu writes that Haskell
supports “multi-methods”



Using multi-methods, I could write (in pseudo code)
collide (Asteroid, Planet) = an asteroid hit a planet
collide (Asteroid, Earth) = the end of the dinos
...
collide (Planet, Asteroid) = collide (Asteroid, Planet)
collide (Earth, Asteroid)  = collide (Earth, Asteroid)


Hi, In Haskell you can use multi parameter type classes to solve this 
problem:


{-# OPTIONS_GHC -fglasgow-exts
   -fallow-undecidable-instances
   -fallow-overlapping-instances #-}

module Collide where

class Collide a b where
   collide :: (a,b) - String

data Solid = Solid
data Asteroid = Asteroid
data Planet = Planet
data Jupiter = Jupiter
data Earth = Earth

instance Collide Asteroid Planet where
   collide (Asteroid, Planet) = an asteroid hit a planet

instance Collide Asteroid Earth where
   collide (Asteroid, Earth) = the end of the dinos

-- Needs overlapping and undecidable instances
instance Collide a b = Collide b a where
   collide (a,b) = collide (b, a)

-- ghci output
*Collide collide (Asteroid, Earth)
the end of the dinos
*Collide collide (Earth, Asteroid)
the end of the dinos

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


Re: [Haskell-cafe] Newbie question: multi-methods in Haskell

2007-08-06 Thread Brian Hulley

Dan Weston wrote:
Remember that type classes do not provide object-oriented 
functionality. The dispatch is static, not dynamic. Although OOP can 
be simulated in Haskell, it is not a natural idiom. If you need 
dynamic dispatch (including multiple dispatch), you may want to 
reconsider your solution.
Dynamic dispatch is easily added to Haskell code by using an existential 
to represent any collision:


{-# OPTIONS_GHC -fglasgow-exts -fallow-undecidable-instances 
-fallow-overlapping-instances #-}


module Collide where

-- Changed to a single param to make life easier...
class Collide a where
   collide :: a - String

data Solid = Solid
data Asteroid = Asteroid
data Planet = Planet
data Jupiter = Jupiter
data Earth = Earth

instance Collide (Asteroid, Planet) where
   collide (Asteroid, Planet) = an asteroid hit a planet

instance Collide (Asteroid, Earth) where
   collide (Asteroid, Earth) = the end of the dinos

-- Needs overlapping and undecidable instances
instance Collide (a, b) = Collide (b, a) where
   collide (a,b) = collide (b, a)

-- This is how you get dynamic dispatch in Haskell
data Collision = forall a. Collide a = Collision a

instance Collide Collision where
   collide (Collision a) = collide a

-- ghci output
*Collide let ae = Collision (Asteroid, Earth)
*Collide let pa = Collision (Planet, Asteroid)
*Collide collide ae
the end of the dinos
*Collide collide pa
an asteroid hit a planet
*Collide map collide [ae, pa]
[the end of the dinos,an asteroid hit a planet]


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


Re: [Haskell-cafe] Newbie question: multi-methods in Haskell

2007-08-06 Thread Brian Hulley

peterv wrote:

This is very nice, but it does not really solve the original problem.
  
To get Haskell to choose the best fit it's necessary to encode the 
location of each element in the hierarchy, so that elements deeper in 
the hierarchy are more instantiated than those at the top. Then instance 
selection chooses the best fit by just choosing the most instantiated match.


Encoding can be done using phantom types, so a generic solid has the path

IsSolid s

a planet has

IsSolid (IsPlanet p)

and a specific planet eg Earth has path

IsSolid (IsPlanet Earth)

A newtype can be used to associate the path with the actual object:

newtype InH path body = InH body

so Earth is represented by

InH Earth :: InH (IsSolid (IsPlanet Earth)) Earth

A class with a functional dependency gives us the mapping between 
concrete objects and the objects as viewed by the hierarchy:


class ToH body path | body - path where
toH :: body - InH path body
toH = InH

The functional dependency means that the path (location in the 
hierarchy) is uniquely determined by the body, and instance decls then 
define this relationship:



instance ToH Asteroid (IsSolid Asteroid)
instance ToH Jupiter (IsSolid (IsPlanet Jupiter))
instance ToH Earth (IsSolid (IsPlanet Earth))


The code is below but as you can see the OOP encoding in Haskell becomes 
quite heavy and clunky so this style is probably not ideal for a real 
program - Tillmann's suggestion to use algebraic datatypes instead is 
more idiomatic - but anyway here goes:


{-# OPTIONS_GHC -fglasgow-exts -fallow-undecidable-instances
-fallow-overlapping-instances #-}

module Collide where

class Collide a where
collide :: a - String

data Asteroid = Asteroid
data Jupiter = Jupiter
data Earth = Earth


data IsSolid a
data IsPlanet a

newtype InH path body = InH body

class ToH body path | body - path where
toH :: body - InH path body
toH = InH

instance ToH Asteroid (IsSolid Asteroid)
instance ToH Jupiter (IsSolid (IsPlanet Jupiter))
instance ToH Earth (IsSolid (IsPlanet Earth))


data Collision = forall a. Collide a = Collision a

mkCollision
:: (ToH a pa, ToH b pb, Collide (InH pa a, InH pb b))
= a - b - Collision
mkCollision a b = Collision (toH a, toH b)


instance Collide (InH (IsSolid a) aa, InH (IsSolid b) bb) where
collide _ = generic collision

instance Collide (InH (IsSolid Asteroid) Asteroid, InH (IsSolid 
(IsPlanet bb)) cc) where

collide _ = an asteroid hit a planet

instance Collide (InH (IsSolid (IsPlanet a)) aa, InH (IsSolid Asteroid) 
Asteroid) where

collide _ = an asteroid hit a planet

instance Collide (InH (IsSolid Asteroid) Asteroid, InH (IsSolid 
(IsPlanet Earth)) Earth) where

collide _ = the end of the dinos

instance Collide (InH (IsSolid (IsPlanet Earth)) Earth, InH (IsSolid 
Asteroid) Asteroid) where

collide _ = the end of the dinos

instance Collide Collision where
collide (Collision a) = collide a

--- ghci output

*Collide mapM_ putStrLn (map collide
[ mkCollision Asteroid Earth
, mkCollision Earth Asteroid
, mkCollision Jupiter Asteroid
, mkCollision Asteroid Jupiter
, mkCollision Asteroid Asteroid
])
the end of the dinos
the end of the dinos
an asteroid hit a planet
an asteroid hit a planet
generic collision
*Collide

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


[Haskell-cafe] Re: monad subexpressions

2007-08-05 Thread Brian Hulley

On Fri Aug 3 06:06:31 EDT Neil Mitchell wrote:
 What are the semantics of
  do b  f (- a)
 where does the evaluation of a get lifted to?

I suggest the execution of (a) should be done immediately before the 
action obtained by applying the monadic function whose argument it is 
part of:


  do b  ( a = \ra - f ra)

Similarly, I'd desugar

  if (- a) then f (- b) else g (- c)

to

  a = \ra - if ra then (b = \rb - f rb) else (c = \rc - g rc)

I think it would just be confusing to have to think about lines in the 
do block since do blocks are just syntactic sugar. The only possible 
thing that might be needed by the do block is to define what monad the 
action should be evaluated in.


Perhaps the rule could be that if (- a) occurs in some expression the 
compiler should search for the nearest enclosing do block to identify 
which monad (a) should be evaluated in, then should again search 
outwards from the expression (- a) to find the nearest enclosing 
expression (mexp) which yields a result in that same monad, then desugar 
to (a = \ra - mexp') where mexp' is obtained from mexp by replacing 
that occurrence of (- a) by (ra). (Evaluations would be done in the 
same order as depth first traversal of their occurrences in mexp)


Regarding objections by others about (- a) being confused with a 
section, (-) is not a valid operator therefore it can't be part of a 
section so no confusion should arise imho...


Best regards, Brian.



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


[Haskell-cafe] Using Haskell to investigate ML's value restriction

2007-07-18 Thread Brian Hulley

Hi,
Ii is interesting that in ML, the presence of mutable ref cells and 
parametric polymorphism requires the whole language to be dominated by a 
value restriction [1] to ensure that the type system remains sound, 
whereas in Haskell, because IORef's can only be created (and used) in 
the IO monad, no such restriction is necessary.


I've often wondered why such a simple thing as using a monad has this 
magical effect, especially since it seems to me that the real problem 
lies in the fact that type variables in HMD type inference are not 
generalised properly due to the absence of an explicit representation of 
the quantifier, so I decided to try using Haskell's more modern type 
system to investigate further, using the IO monad together with 
(unsafePerformIO) and (evaluate) to simulate the execution of an ML program:


{-# OPTIONS_GHC -fglasgow-exts #-}
module Test where

import Data.IORef
import System.IO.Unsafe (unsafePerformIO)
import Control.Exception (evaluate)

ref v = unsafePerformIO $ newIORef v

put r f = unsafePerformIO $ writeIORef r f

get r = unsafePerformIO $ readIORef r

-- Gives a core dump as expected
test1 :: IO ()
test1 = do
   let r  = ref (\x - x)
   evaluate (put r (\x - x + 1))
   evaluate (get r True)
   return ()

(test1) is based on one of the ML examples in [1], and when executed, 
causes a segmentation fault. The reason seems to be the strange type 
that is assigned to (r):

*Test let r = ref (\x - x)
*Test :t r
r :: forall t. IORef (t - t)
*Test

(To run this you need to use ghci -fglasgow-exts Test.hs to get ghci 
6.6.1 to display the quantifier.)


What's strange (to me) about the above typing is that the forall has 
moved outside the IORef constructor. In other words, although we 
supplied the constructor with a function which can operate on any value, 
we got back something which, for any value, contains a function which 
can operate on it.


The reason afaics that (test1) goes wrong is that the let binding causes 
(r) to be bound to the type above, so the argument matches both


   forall a. Num a = a - a

and

   Bool - Bool

so the action (evaluate (get r True)) tries to apply a function which 
expects a number to a Bool.


However if we add an explicit type to (r) to get (what I see as) the 
expected quantification, the type checker correctly rejects the program:


test2 :: IO ()
test2 = do
   let r :: IORef (forall a. a - a) = ref (\x - x)
   evaluate (put r (\x - x + 1))
   evaluate (get r True)
   return ()

no instance for Num a ...

which might seem like a reason not quite related to our chain of thought 
so I also tested this using:


test3 :: IO ()
test3 = do
   let r :: IORef (forall a. a - a) = ref (\x - x)
   evaluate (put r (\'c' - 'c'))
   evaluate (get r True)
   return ()

which gives couldn't match expected type `a' (a rigid variable) against 
inferred type `Char'. In other words, the IORef must always contain a 
function that works with anything - we can't just give it a more 
specialized function, so the program is rejected for the reasons we expect.


Interestingly, even without type annotations, if we use a case instead 
of a let, the typechecker also rejects the program:


test4 :: IO ()
test4 =
   case ref (\x - x) of
   r - do
   evaluate (put r (\'c' - 'c'))
   evaluate (get r True)
   return ()

this time by noting that (Bool - t) does not match (Char - Char). This 
illustrates (afaiu) that case does not introduce any quantification, 
in contrast to let hence the uninstantiated meta-tyvars of r have to 
unify with both its uses.


In conclusion, it seems that the magic given by always having to use 
IORef's inside the IO monad (without unsafePerformIO of course) is due 
to the fact that when used this way types involving IORefs never get 
generalized wrongly since they're never created by a let binding.


Another conclusion is that if we wanted at some point to have another 
new strict language with Haskell's nice type system and syntax as an 
alternative to the ML family, and we also wanted to have references (and 
continuations), then either the rule for generalizing the meta-type 
variables in a let binding would have to be changed or else we would 
still have to use monads.


I'd be interested to know if the use of impredicative types would 
automatically solve the wierd quantification problem, since:


*Test :t ref
ref :: forall a. a - IORef a

therefore applying this to an argument of type (forall b. b - b) should 
hopefully give a result of type (IORef (forall b. b - b)), thus the use 
of impredicative types might allow such a strict variant of Haskell to 
use side-effects instead of monads while still retaining type soundness... ?


Best regards,
Brian.

[1] http://www.smlnj.org/doc/Conversion/types.html
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] Proposal for allowing more use of layout to avoid parentheses and commas

2007-02-03 Thread Brian Hulley

Hi,
Following a recent thread on the Haskell' mailing list about the nusiance of 
having to deal with commas in tuples (when cutting and pasting things to 
re-order the elements there's always a pesky comma left over in the wrong 
place), I've written up a proposal for a very simple syntax tweak that would 
allow you to use the layout rule for function arguments, tuple/list/record 
contents etc for some future version of Haskell at 
http://www.haskell.org/haskellwiki/Accessible_layout_proposal


This post is not intended to spark a lot of discussion just to point out the 
existence of the page for anyone interested. I've also added a link to all 
the new proposals from http://www.haskell.org/haskellwiki/Future .


(If I don't reply to any follow up posts to this thread it's not because I'm 
ignoring them. It will just be because I have to try to get down to actually 
writing more of my program in the next few weeks, and I find thinking up 
ideas and reading posts, books, cooking, shopping, watching dvds etc, is 
infinitely more diverting than the painstakingly hard work of actual coding 
(though of course it's great in the rare occasions when things fall into 
place) ... ;-))


Brian.
--
http://www.metamilk.com 


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


Re: [Haskell-cafe] Re: Channel9 Interview: Software Composability andtheFu ture of Languages

2007-01-31 Thread Brian Hulley

Donald Bruce Stewart wrote:

magnus:

All I'm trying to say is that imperative thinking is so common
outside of CS/math and we learn it so early on in life that we
probably can consider it the natural thinking way.


   foldl (\water dish - wash water dish) soapywater dishes ::
[Dishes]

 ^^ type error

I hope they weren't expensive dishes because as each dish is washed it 
dissolves into the water never to be seen again! :-)


Brian.
--
http://www.metamilk.com 


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


Re: [Haskell-cafe] Trouble understanding records and existential types

2007-01-25 Thread Brian Hulley

On Thursday, January 25, 2007 7:08 AM, John Ky wrote:

On 1/25/07, Brandon S. Allbery KF8NH [EMAIL PROTECTED] wrote:
I'm probably missing something, but:

(a) Why not:

data ANode
= Branch { name :: String, description :: String,
children :: [AnyNode] }
  | Leaf { name :: String, value :: String } -- this reuse


Would I be able to this?

  getLeaves :: ANode - [Leaf]

If not, is it the case that people generally don't bother and do this 
instead?


  getLeaves :: ANode - [ANode]


As has been pointed out, Leaf is a data constructor not a type so you'd have 
to use [ANode].

Inspired by the problem I tried a GADT:

   data IsLeaf
   data IsBranch

   data ANode a where
   Branch :: String - String - [forall b. ANode b] - ANode IsBranch
   Leaf :: String - String - ANode IsLeaf

   getLeaves :: ANode IsBranch - [ANode IsLeaf]
   getLeaves (Branch _ _ ls) = leaves ls

   leaves :: [forall b. ANode b] - [ANode IsLeaf]
   leaves (l@(Leaf _ _) : ls) = l : leaves ls
   leaves (Branch _ _ ls : lls) = leaves ls ++ leaves lls

but unfortunately the above code generates the following error by GHC6.6:

   Couldn't match expected type `forall b. ANode b'
   against inferred type `ANode a'
   In the pattern: Leaf _ _
   In the pattern: (l@(Leaf _ _)) : ls
   In the definition of `leaves':
   leaves ((l@(Leaf _ _)) : ls) = l : (leaves ls)

Just out of curiosity, does anyone know why the above code doesn't compile 
ie why is the inferred type for the pattern:


   Leaf _ _

(ANode a) and not (ANode IsLeaf)?

Thanks, Brian.
--
http://www.metamilk.com 


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


Re: [Haskell-cafe] Trouble understanding records and existential types

2007-01-25 Thread Brian Hulley

Chris Kuklewicz wrote:

This is how I would write getLeaves, based on your GADT:


data IsLeaf
data IsBranch

newtype Node = Node { getNode :: (forall c. ANode c) }

data ANode :: * - * where
Branch :: String - String - (ANode a,ANode b) - [Node] -

ANode IsBranch
Leaf :: String - String - ANode IsLeaf

getLeaves :: ANode a - [ANode IsLeaf]
getLeaves (Branch _ _ (l1,l2) rest) = getLeaves l1 ++ getLeaves l2
++ concatMap (getLeaves.getNode) rest
getLeaves x@(Leaf {}) = [x]


Thanks Chris - that's really neat!
I see it's the explicit wrapping and unwrapping of the existential that 
solves the typechecking problem, and the use of newtype ensures there's no 
run-time penalty for this.
Also the wrapping of the existential allowed higher order functions to be 
used making the code much neater.
Regarding the question of why in the original example the typechecker was 
trying to match (forall b.ANode b) against (ANode a) and not (ANode IsLeaf), 
I think the answer is probably that the typechecker first finds the MGU of 
the types occupying the same position in all the left hand sides first, then 
it tries to match this against the declared type at that position, whereas 
for the original example to have typechecked it would have to treat each 
equation separately. Anyway it's now an irrelevant point given the clarity 
of your solution which compiles fine,


Best regards, Brian.
--
http://www.metamilk.com 


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


Re: [Haskell-cafe] basic field questions

2007-01-24 Thread Brian Hulley

jamin1001 wrote:

Hi, I am new at Haskell and have some basic questions.
So then how should this be done?  What if I want to do something like

data Chair = Chair {pos:: Int, color :: Int}
data Table = Table {pos:: Int, color :: Int}


Unfortunately you have to think up different names for all constructors and 
field names that are declared anywhere in the same module. A possible 
methodical way to do this is to prefix all names by the type name (with 
first letter lowercase of course) eg:


   data Chair = Chair {chair_pos:: Int, chair_color :: Int}
   data Table = Table {table_pos:: Int, table_color :: Int}

The reason is that when you declare a fieldname this also introduces a top 
level function with the same name which returns the relevant component of 
the record ie in the above the following top level functions are generated 
by the compiler:


   chair_pos :: Char - Int
   chair_color :: Chair - Int
   table_pos :: Table - Int
   table_color :: Table - Int




Also, could someone tell me why this doesn't compile in GHC:

data Test = A {a::Int} | B {a::Int, b::Int}
data Test2 = C {c::A}

(Test2 line): Not in scope: type constructor or class 'A'


(A) is a data constructor whereas you need a type here, so it should be:

   data Test2 = C {c :: Test}

Brian.
--
http://www.metamilk.com 


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


Re: [Haskell-cafe] IO is not a monad

2007-01-23 Thread Brian Hulley

Yitzchak Gale wrote:

I wrote:

Prelude let f .! g = ((.) $! f) $! g
Prelude let f = undefined :: Int - IO Int
Prelude f `seq` 42
*** Exception: Prelude.undefined
Prelude ((= f) . return) `seq` 42
42
Prelude ((= f) .! return) `seq` 42
42


Duncan Coutts wrote:

Perhaps I'm missing something but I don't see what's wrong.


The monad laws say that (= f) . return must be
identical to f.


I thought it was:

   return x = f = f x

so here the lhs is saturated, so will hit _|_ when the action is executed 
just as the rhs will.
I think the problem you're encountering is just that the above law doesn't 
imply:


   (= f) . return = f

in Haskell because the lhs is of the form \x - _|_ whereas the rhs, which 
should really be of the form \x - _|_, is actually _|_ already(!) so the 
_|_ has effectively been allowed to jump to the left of the arrow hence the 
inequality detected by seq.


Perhaps a solution would be to force _|_ to respect the shape of the type, 
thus non-terminating values of type a - b would be given the value \_ - 
_|_ instead of _|_ ?


Regards, Brian.
--
http://www.metamilk.com 


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


Re: [Haskell-cafe] IO is not a monad

2007-01-23 Thread Brian Hulley

Brian Hulley wrote:

Yitzchak Gale wrote:

I wrote:

Prelude let f = undefined :: Int - IO Int
Prelude f `seq` 42
*** Exception: Prelude.undefined
Prelude ((= f) . return) `seq` 42
42

The monad laws say that (= f) . return must be
identical to f.


I thought it was:

   return x = f = f x

so here the lhs is saturated, so will hit _|_ when the action is
executed just as the rhs will.
I think the problem you're encountering is just that the above law
doesn't imply:

   (= f) . return = f

in Haskell

ok so far...


because the lhs is of the form \x - _|_


No I got this wrong. Evaluating the lhs to WHNF doesn't hit the _|_. 
(Incidentally the version using .! evaluates to exactly the same thing since 
(= f) `seq` ((= f) . return) = ((= f) . return) since (\x - x = f) 
is already in WHNF afaiu)


Brian.
--
http://www.metamilk.com 


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


Re: [Haskell-cafe] IO is not a monad

2007-01-23 Thread Brian Hulley

Brian Hulley wrote:

Brian Hulley wrote:

Yitzchak Gale wrote:

I wrote:

Prelude let f = undefined :: Int - IO Int
Prelude f `seq` 42
*** Exception: Prelude.undefined
Prelude ((= f) . return) `seq` 42
42

The monad laws say that (= f) . return must be
identical to f.


I thought it was:

   return x = f = f x

so here the lhs is saturated, so will hit _|_ when the action is
executed just as the rhs will.


Ooops! But that does not mean the equation holds because for example

   Prelude (return 3 = f) `seq` 42
   42
   Prelude (f 3) `seq` 42
   *** Exception: Prelude.undefined

In the lhs you only hit _|_ when the composite (=) action is actually 
being executed whereas in the rhs you hit _|_ when computing the function 
which will return the action to execute so there is difference.


Brian.
--
http://www.metamilk.com 


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


Re: [Haskell-cafe] Re: Article review: Category Theory

2007-01-19 Thread Brian Hulley

Lennart Augustsson wrote:


On Jan 19, 2007, at 08:05 , [EMAIL PROTECTED] wrote:

Thus, Hask is not a category, at least not as defined in the article.
The problem is that (either) morphisms or the morphism composition
('.')
are not internalized correctly in Haskell.




And this is why some of us think that adding polymorphic seq to
Haskell was a mistake. :(


I've often wondered why seq is the primitive and not $!
Would this solve the problem?
Is there any solution that would allow excess laziness to be removed from a 
Haskell program such that Hask would be a category?


Thanks, Brian.
--
http://www.metamilk.com 


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


[Haskell-cafe] seq (was: Article review: Category Theory)

2007-01-19 Thread Brian Hulley

Neil Mitchell wrote:

Hi Brian,

Is there any solution that would allow excess laziness to be removed
from a Haskell program such that Hask would be a category?


class Seq a where
   seq :: a - b - b

Then you have a different seq based on the types, and it doesn't go
wrong. You would probably want deriving Seq support.


This seems an amazingly neat solution to a really terrible problem, so:

1) Does anyone know why this was not used in the first place?

2) Would it be good to use this in future versions of Haskell?

3) Is there any practical program which requires the current seq that could 
not be rewritten to use the typeclass seq?


Thanks, Brian.
--
http://www.metamilk.com 


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


Re: [Haskell-cafe] Re: Article review: Category Theory

2007-01-18 Thread Brian Hulley

Johan Gršnqvist wrote:

Ulf Norell skrev:


On Jan 16, 2007, at 7:22 PM, David House wrote:


In the section on the category laws you say that the identity
morphism should satisfy

  f . idA = idB . f

This is not strong enough. You need

  f . idA = f = idB . f



(I do not know category theory, but try to learn from the
tutorial/article/introduction.)

Given this, and looking at the figure accompanying exercise 2. Can I
not then show that f=h from:

f.g = idA (f.g is A - A and idA is the only morphism A - A,
closedness gives the equality)

h.g = idA (same argument)
g.f = g.h = idB (same argument)

thus (using the laws for id and associativity)

f =  idA . f  =  (h . g) . f = h . (g . f)  = h . idB  = h

Thus in the figure f=h must hold, nad one arrow can be removed from
 the graph.


But f /= h so by the above reasoning you get a proof by contradiction that 
the figure is not a category.


Brian.
--
http://www.metamilk.com 


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


Re: [Haskell-cafe] Article review: Category Theory

2007-01-17 Thread Brian Hulley

David House wrote:

http://en.wikibooks.org/wiki/Haskell/Category_theory
I'd love comments from newcomers and experts alike regarding my
approach, the content, improvements and so on. Of course, it's on the
wikibook, so if you have anything to add (that's not _too_ substantial
otherwise I'd recommend discussion first) then go ahead.


Hi David,

In the introduction you say that Set is the category of all sets with 
morphisms as standard functions and composition as standard function 
composition.


But in the second exercise in the intro it's clear that function composition 
is not associative. Therefore surely this means everything based on function 
composition can't be a category?


Also, why does this exercise contain redundant morphisms (I hope I'm not 
spoiling it for anyone by saying this or perhaps I've just totally 
misunderstood everything)?


Thanks, Brian.
--
http://www.metamilk.com 


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


Re: [Haskell-cafe] Article review: Category Theory

2007-01-17 Thread Brian Hulley

Brian Hulley wrote:

David House wrote:

http://en.wikibooks.org/wiki/Haskell/Category_theory

But in the second exercise in the intro it's clear that function
composition is not associative.


Apologies. I got totally confused with the way function composition is back 
to front etc.

I still have no idea what the solution to the second exercise is though.

Thanks, Brian.
--
http://www.metamilk.com 


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


Re: [Haskell-cafe] Article review: Category Theory

2007-01-17 Thread Brian Hulley

Yitzchak Gale wrote:

David House wrote:

I've added a bit more explanation, so it may now be palatable. It is
quite a hard exercise, though, perhaps it shouldn't come so early on.


In my opinion, it is now much more clear. And it is a very
instructive example.

If people still find it too hard, you could add the additional
hint: Keep in mind that there are no morphisms
other than the ones shown in the diagram.


Ok I understand it now, because David has just clarified offlist the thing 
that puzzled me about the diagram: namely that morphisms have an 
individuality of their own that isn't fully determined by the lhs and rhs of 
the arrow like the relationship between a function and its type.


Brian.
--
http://www.metamilk.com 


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


Re: [Haskell-cafe] Redefining superclass default methods in a subclass

2007-01-15 Thread Brian Hulley

Meng Wang wrote:

Hi Brian,

Thank you for starting the thread. We (Martin Sulzmann and me)
proposed a type class extension which allows modular extension of
superclasses (a complement of subclass extension). The idea has been
shown to be particularly useful in (but not limited to) encodings of
generic programming with type classes. A brief introduction of the
proposal is documented in our wiki:
http://taichi.ddns.comp.nus.edu.sg/taichiwiki/GPHomePage. I will try
to add it as a link in yours soon.


A more detailed and formal description of the proposal can be found
in our Workshop on Generic Programming 06 paper which is available at
http://www.comp.nus.edu.sg/~sulzmann
http://web.comlab.ox.ac.uk/oucl/work/meng.wang/


Thanks - I've added the above links to 
http://www.haskell.org/haskellwiki/Class_system_extension_proposal along 
with a one-line summary which I'm sure is totally imperfect but hopefully 
not too misleading ;-)


Best regards, Brian.
--
http://www.metamilk.com 


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


Re: [Haskell-cafe] Redefining superclass default methods in a subclass

2007-01-09 Thread Brian Hulley

Simon Peyton-Jones wrote:

One of the great things about John's class-alias proposal is that
John worked out a lot of details and captured them in a web page,
rather than it getting buried in an email thread.

If you have ideas to refine his proposal, it'd be good to see if,
with him, you can come up with a unified design, and again capture it
in a Wiki page or something.


I've started a page at 
http://www.haskell.org/haskellwiki/Class_system_extension_proposal
John - I haven't added anything about your class alias proposal because 
you've copyrighted your proposal and I don't want to do the wrong thing ;-) 
Can you add a section for your proposal (or containing a link to your 
proposal) on his page?


Please could everyone who has any other ideas about class system extensions 
add them to the page above so that we have a central location. Hopefully it 
will gradually become clear what all the issues are and perhaps a path for 
trying to implement some extensions in order of difficulty.


Thanks, Brian.
--
http://www.metamilk.com 


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


Re: [Haskell-cafe] Redefining superclass default methods in a subclass

2007-01-09 Thread Brian Hulley

Brian Hulley wrote:

Simon Peyton-Jones wrote:

One of the great things about John's class-alias proposal is that
John worked out a lot of details and captured them in a web page,
rather than it getting buried in an email thread.

If you have ideas to refine his proposal, it'd be good to see if,
with him, you can come up with a unified design, and again capture it
in a Wiki page or something.


I've started a page at
http://www.haskell.org/haskellwiki/Class_system_extension_proposal
John - I haven't added anything about your class alias proposal
because you've copyrighted your proposal and I don't want to do the
wrong thing ;-) Can you add a section for your proposal (or
containing a link to your proposal) on his page?

  ^^^
Apologies for typo - should be this page

Best regards, Brian.
--
http://www.metamilk.com
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] why can't you surround (+) in backticks and have it beinfix?

2007-01-08 Thread Brian Hulley

[EMAIL PROTECTED] wrote:

David House wrote:


You can fake this:

(-!) = ($)
(!-) = flip ($)

foo -! liftM2 (,) !- bar


Was anyone in that brainstorm thinking of Chung-chieh Shan's
-: and :-
(http://www.haskell.org/pipermail/haskell-cafe/2002-July/003215.html)
or was the similarity just a really cool coincidence?


I hope no-one seriously thinks the above syntax is clearer than:

   liftM2 (,) foo bar

Brian.
--
Operators: one small step for compilers, one giant leap for obfuscation.

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


[Haskell-cafe] Why does the wiki search facility not work properly?

2007-01-07 Thread Brian Hulley

Hi,
There is a page on the Haskell Wiki titled Talk:SantaClausProblem 
subtitled Beautiful concurrency. However typing any of the following into 
the search box *doesn't* lead to the page:


   Santa
   talk:santaclausproblem
   beautiful
   beautiful concurrency
   Talk:Santa

In fact to get the page you have to type the *exact* full title in the 
*exact* case. Luckily I could always refer back to SimonPJ's post to the 
Haskell mailing list to find the link to the page, but I think this 
situation is really bad because it means that things on the wiki are more or 
less just being thrown down a gaping void never to be seen again unless you 
know which catagories to look in from the main page.


Another point is that the word beautiful does occur on the page but the 
page is not included in the list of page text matches. Perhaps the site is 
not being automatically re-indexed frequently enough? There is also a bunch 
of check boxes at the bottom of the search results page that doesn't seem to 
do anything either except cause nothing at all to happen when you click 
search unless the (Main) box is the only box ticked.


Anyway I thought I'd just point this out in case anyone knows how to fix it.

Thanks, Brian.
--
http://www.metamilk.com 


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


Re: [Haskell-cafe] Redefining superclass default methods in a subclass

2007-01-06 Thread Brian Hulley

Bulat Ziganshin wrote:

Hello Brian,

Thursday, January 4, 2007, 10:00:05 PM, you wrote:


deeper, the programmer is burdened more and more by the need to
cut-and-paste method definitions between instances because Haskell
doesn't allow a superclass (or ancestor class) method default to be
redefined in a subclass.


i've runned into this problem with Streams library. finally i've
decided to wrote bodies of such methods outside of class:

[example snipped]

Hello Bulat,

Thanks for the workaround, which solves the need to copy and paste method 
bodies though not the problem of having to write out instance decls for a 
potentially large chain of classes leading to the subclass of interest. Part 
of the motivation for proposing that a superclass method default could be 
redefined in a subclass (or a particular instance) is that it would allow 
some refactorings of the class hierarchy without affecting code that just 
uses the subclass - in particular it would allow existing code using Monad 
to compile unchanged even when Monad moved down to Functor = Applicative = 
Monad because return and = are enough to get completely defined instances 
for Functor and Applicative.


Best regards, Brian.
--
http://www.metamilk.com 


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


Re: [Haskell-cafe] Stupid newbie question

2007-01-06 Thread Brian Hulley

Brian Hurt wrote:

nth 0 (x:xs) = Some x
nth i (x:xs) = if i  0 then Empty else nth (i-1) xs
nth i [] = Empty

[blows stack on large i]

As other people have pointed out, this is due to laziness. I'd write it 
like:


   nth 0 (x:_) = Some x
   nth i (_:xs) = of i  0 then Empty else (nth $! i-1) xs
   nth _ [] = Empty

where a general rule of thumb is always to replace (fun intexp) by (fun $! 
intexp) whenever intexp is just a trivial arithmetic expression that doesn't 
involve traversing (ie forcing of) any other data structure.


Brian.
--
http://www.metamilk.com 


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


Re: [Haskell-cafe] Stupid newbie question

2007-01-06 Thread Brian Hulley

Brian Hulley wrote:

Brian Hurt wrote:

nth 0 (x:xs) = Some x
nth i (x:xs) = if i  0 then Empty else nth (i-1) xs
nth i [] = Empty

[blows stack on large i]

As other people have pointed out, this is due to laziness. I'd write
it like:

   nth 0 (x:_) = Some x
   nth i (_:xs) = of i  0 then Empty else (nth $! i-1) xs

  ^^^ -- oops!


   nth _ [] = Empty


I think the above code would be more efficient written as:

   nth n xs = if n  0 then Empty else nth' n xs
   where
   nth' 0 (x:_) = Some x
   nth' i (_:xs) = (nth' $! i - 1) xs
   nth' _ _ = Empty

since the first 2 cases deal with every situation where we've got a 
non-empty list and an index = 0 (so no need to keep checking that the index 
is = 0 in the second case - instead the test can be moved outside the 
loop) and there's no need to pattern match against [] in the last case 
because we already know this must be an empty list.
(Though in general it's probably a good idea to make each pattern as 
independent as possible when writing a function so that if some cases of a 
function are later edited there's more chance of the compiler being able to 
lead you to errors via the incomplete patterns warning - hopefully the 
compiler can optimize out any redundant checks)


Brian.
--
http://www.metamilk.com 


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


Re: [Haskell-cafe] Stupid newbie question

2007-01-06 Thread Brian Hulley

Brian Hulley wrote:

Brian Hulley wrote:

Brian Hurt wrote:

nth 0 (x:xs) = Some x
nth i (x:xs) = if i  0 then Empty else nth (i-1) xs
nth i [] = Empty

[blows stack on large i]

As other people have pointed out, this is due to laziness. I'd write
it like:

   nth 0 (x:_) = Some x
   nth i (_:xs) = of i  0 then Empty else (nth $! i-1) xs

  ^^^ -- oops!


   nth _ [] = Empty


Actually I see I should have read Jeremy Shaw's answer more carefully before 
giving my own since I'd missed the point about the problem being with the 
list itself not the decrementing of (i) (which wouldn't be a problem since 
it is immediately forced on the next iteration by the comparison of i to 0).


The answer therefore lies in the laziness of the makelist function which 
could be solved by:


   makelist i = i : (makelist $! i - 1)

Jeremy Shaw wrote:

pps. I didn't explain why [1..100] works, but [1..] fails, because
I don't know :) It's a bit suprising to me...


I think this might be because the code that produces the list [1..100] 
would have to be something like:


   produce n i = if i  n then i : produce n (i +1) else []

so each element of the list is now forced by the comparison with n, so even 
though the end of the list will be a thunk when 100 has not yet been 
reached, none of the elements are thunks.


Anyway it was certainly not a stupid question - thanks for asking it.

Best regards, Brian.
--
http://www.metamilk.com 


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


[Haskell-cafe] Redefining superclass default methods in a subclass

2007-01-04 Thread Brian Hulley

Hi,
Looking at some of the ideas in 
http://www.haskell.org/haskellwiki/The_Other_Prelude , it struck me that the 
class system at the moment suffers from the problem that as hierarchies get 
deeper, the programmer is burdened more and more by the need to 
cut-and-paste method definitions between instances because Haskell doesn't 
allow a superclass (or ancestor class) method default to be redefined in a 
subclass.


For example, consider this part of a proposal for Functor = Applicative = 
Monad:


   -- I've just used 'm' so it's easy to see what parts are relevant to 
Monad

   class Functor m where
   fmap :: (a - b) - m a - m b

   class Functor m = Applicative m where
   return :: a - m a

   (*) :: m (a - b) - m a - m b

   () :: m a - m b - m b
   ma  mb = -- left as exercise for a rainy day!

   class Applicative m = Monad m where
   (=) :: m a - (a - m b) - m b

The problem with this is that whereas someone defining a Monad at the moment 
only needs to define (return) and (=), with the above, though it gives 
obvious advantages in flexibility, generality etc, defining a new Monad 
involves providing methods (in instance decls) for fmap and (*) as well, 
and the default method for () is


   ma  mb = (fmap (const id) ma) * mb

(from that page above) which I'm sure everyone will agree is a *lot* more 
complicated than:


   ma  mb = ma = (\_ - mb)

Not only is the first definition for () more complicated, it obscures the 
simple fact that for monads it's just a trivial special-use case of = 
where the bound argument is ignored.


Therefore I'm wondering if it would be possible to allow default methods for 
a superclass to be defined, or redefined, in a subclass, so we could write:


   class Applicative m = Monad m where
   (=) :: m a - (a - m b) - m b

   mf * ma = mf = \f - ma = \a - return (f a)

   ma  mb = ma = \_ = - mb

   fmap f ma = ma = \a - return (f a)

(I know the above can be written in a more point-free style but I wrote it 
like that to make it easy to understand what's happening.)


The essential point here (excuse the pun :-) ) is that it is impossible to 
write the default methods in the class in which the operation is defined, 
because the implementation depends on methods of the relevant subclass (and 
will therefore be different for different subclasses though not for each 
particular instance of a given ancestor class of a  particular subclass). As 
Haskell stands at the moment, we are forced to cut and paste identical 
methods for each individual instance of each ancestor class of a particular 
subclass because we can't override an ancestor class method in the *class* 
decl for a subclass.


The type class system at present is based on the idea that you can define 
related methods together and in terms of each other, at one level of the 
hierarchy. However as the above example shows, related methods sometimes 
need to be spread over the hierarchy but we still want to be able to define 
default implementations of them in terms of each other.


Perhaps there is some reason this can't be done?

Brian.
--
http://www.metamilk.com 


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


Re: [Haskell-cafe] Redefining superclass default methods in a subclass

2007-01-04 Thread Brian Hulley

Roberto Zunino wrote:

Brian Hulley wrote:

because Haskell doesn't allow a superclass (or ancestor class)
method default to be redefined in a subclass.


How one would write instances? Using your Monad class, does
   instance Monad F where
  return = ...
  (=) = ...
automatically define an instance for Applicative?


Yes, but I'd make the method names be call-site-bound so the actual method 
that is called is determined by the set of instance decls and class decls 
visible at each particular call site, and any instances that are 
automatically created would be hidden by any explicitly defined instances 
that are visible.




If it does: What if there already is such an instance? Which one gets
used for ()? The user-defined one or the Monad default?


A possible proposal could be:
1) Class and instance decls would allow method implementations to be given 
for any methods in the class or any ancestor class.


2) Whenever an instance decl is visible there would always be a full set of 
instance decls for all ancestor classes, by supplementing the set of 
explicitly given instance decls that are visible by automatically generated 
implicit instance decls.


3) The most specific method implementation would always be chosen (ie prefer 
an explicit instance method over a class method and prefer a subclass method 
to a superclass method)


In particular rule 2) would mean that the actual method used depends on 
what's available at the call site which means that a Haskell program could 
no longer be thought of as being re-written into a single module before 
compilation, since the meaning of overloaded names would be determined by 
(CalledFromModule, Type) not just Type.


(The desire to hide instance decls or have different instance decls for the 
same type within the same program has come up before on the list but 
unfortunately I can't remember who posted something along these lines or 
when.)



Is separate
compilation still possible? (If there is no instance right now, one
might pop out in another module...)



I think it should still be possible because within a module, the 
overloadings would be determined by the set of explicitly defined instances 
in scope in that module. Various optimizations might be more tricky because 
the call site module associated with each overloaded name would need to be 
taken into account when inlining across module boundaries (ie a name used 
inside an inlined function needs to be resolved as if it had been used in 
the module where the function was defined not the module where the function 
is inlined).


For example:

   module A where
   import Proposed.Control.Monad

   data T a = T a
   instance Monad T

   [-# INLINE foo #-}
   foo :: a - T a
   foo = return  -- uses Monad class default
   -- which is inherited from the Applicative
   -- class default

   module B where
   import A
   import Proposed.Control.Monad

   instance Applicative T where
   return x = retB x

   bar :: T a
   bar = return 'q'-- would use (retB)

   zap :: T a
   zap = foo 'q'-- would use (return) from A

A question is whether the extra difficulty in resolving overloadings (for 
human reader as well as complier) is worth the advantages of being able to 
get generated definitions for () for Applicative and (fmap) for Functor 
from a single instance decl for (Monad.=) etc.


[Rearranged]

The class aliases proposal lists several similar shortcomings of the
current class system.
http://repetae.net/john/recent/out/classalias.html


IIUC the class alias proposal is about being able to group classes together 
and deal with them as a whole so similar issues of resolving overloadings 
arising from overlapping aliases/ explicit instance decls etc would arise 
(and I imagine the solutions would lie in similar directions).


Brian.
--
http://www.metamilk.com 


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


Re: [Haskell-cafe] Composing functions with runST

2007-01-01 Thread Brian Hulley

Yitzchak Gale wrote:

Can anyone explain the following behavior (GHCi 6.6):

Prelude Control.Monad.ST runST (return 42)
42
Prelude Control.Monad.ST (runST . return) 42

interactive:1:9:
   Couldn't match expected type `forall s. ST s a'
  against inferred type `m a1'
   In the second argument of `(.)', namely `return'
   In the expression: (runST . return) 42
   In the definition of `it': it = (runST . return) 42


Section 7.4.8 of GHC manual states that a type variable can't be 
instantiated with a forall type, though it doesn't give any explanation why.


Hazarding a guess, I suggest it *might* be due to the fact that

   forall s. ST s a

means

   forall s. (ST s a)

whereas you'd need it to mean

   (forall s. ST s) a

in order for it to unify with (m a).

Just a guess - I'd be interested to know the real reason as well.

Brian.
--
http://www.metamilk.com 


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


Re: [Haskell-cafe] Idiomatic Haskell equivalent of keyword argumentsto functions

2006-12-29 Thread Brian Hulley

Paul Moore wrote:

I'm thinking around the design of a couple of things, and am hitting
an issue which I know how I would solve in Python, but I'm not sure
what a good idiomatic Haskell approach would be.

The problem is that I am trying to write a function which takes a
rather large number of arguments, many of which are optional (ie, have
sensible defaults).


There's an interesting solution to this in section 15 (starting page 53) of 
Magnus Carlsson and Thomas Hallgren's Fudgets thesis available online at: 
http://www.cs.chalmers.se/~hallgren/Thesis/ (Fudgets main page is at 
http://www.cs.chalmers.se/ComputingScience/Research/Functional/Fudgets/ ).


Basically the idea is that for any function which takes lots of params, the 
params are gathered together into a datatype whose details are hidden from 
the user of the function. For each parameter, the user is given a function 
called a Customiser in the thesis, which takes a value of the hidden 
datatype and modifies it by setting the relevant parameter. Multiple params 
can therefore be specified by chaining Customisers together in any order 
with the usual function composition. The original function, instead of 
taking lots of params, now just takes a single parameter: a Customiser, 
which is used to turn the default params into the customised params.
This is similar to the idea of using records but has the advantage that by 
judicious use of typeclasses of which the param data is an instance, you 
don't need to keep on inventing different names for the same thing (eg to 
specify colour for the background of a label control in a GUI or colour for 
a font you could use the name setColour in both cases).
(A possible disadvantage is the overhead of having to create a whole new 
modified version of the parameter record for each Customiser in the 
composition so if efficiency were an issue you'd have to see if the compiler 
could inline the composition of the customiser functions to make it as 
efficient as the built in multiple field record update using rec{a=a', c=c'} 
syntax)



To make things concrete, the example I'm really thinking of is a send
an email function, which would take a subject, a body, a list of
recipients, optional lists of cc and bcc recipients, an optional
mailserver (default localhost), an optional port (default 25), and
possibly optional authentication details. I found a couple of Haskell
modules implementing a SMTP client, but they both just used a list of
positional parameters, which I'm not really happy with. At the very
least, I'd like to wrap them in a nicer interface for my code.



-- hidden from clients
data EmailParams =
   EmailParams
   { subject :: String
   , body :: String
   , recipients :: [Recipient]
   , cc :: [Recipient]
   , bcc :: [Recipient]
   , mailserver :: Mailserver
   , port :: Port
   , authentication :: Authentication
   }

-- record syntax elided to save space
defaultEmailParams = EmailParams   [] [] [] defaultMailserver 
defaultPort defaultAuthentication


--a Customiser visible to clients
setSubject :: String - EmailParams - EmailParams
setSubject s ep = ep{subject = s}

-- etc

send :: (EmailParams - EmailParams) - IO ()
send f = sendInternal (f defaultEmailParams)
   where
   sendInternal :: EmailParams - IO ()
   sendInternal = ...

-- In user code:

main = send (setSubject Test . setBody A test email)

Brian.
--
http://www.metamilk.com 


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


Re: [Haskell-cafe] Seeking advice on a style question

2006-12-27 Thread Brian Hulley

Steve Schafer wrote:

In my text/graphics formatting work, I find myself doing a lot of
pipeline processing, where a data structure will undergo a number of
step-by-step transformations from input to output. For example, I
have a function that looks like this (the names have been changed to
protect the innocent--and to focus on the structure):

 process :: a - b - c - d - e
 process x1 x2 x3 x4 =
   let y01   = f01 x1 x2 x3;
   y02   = f02 x1;
   y03   = f03 y02;
   y04   = f04 y03;
   y05   = f05 x1 y01 y04;
   y06   = f06 x2 y05;
   (y07,y08) = f07 y01 y06;
   y09   = f08 y07;
   (y10,y11) = f09 x2 x4 y09 y08;
   y12   = f10 y10;
   y13   = f11 y12;
   y14   = f12 x1 x2 x3 y01 y13;
   y15   = f13 y14;
   y16   = f14 y15 y11
   in y16


Disclaimer: just re-written by hand so needs double-checking before use:

   process x1 x2 x3 x4 =
   let
   y01 = f01 x1 x2 x3
   (y07, y08) = f07 y01 (f06 x2 (f05 x1 y01 (f04 (f03 y02
   (y10, y11) = f09 x2 x4 (f08 y07) y08
   in
   f14 (f13 (f12 x1 x2 x3 y01 (f11 (f10 y10 y11

You can also make it look more like the diagram by using more indentation 
eg:


   process x1 x2 x3 x4 =
   let
   y01 =
   f01
   x1
   x2
   x3
   (y07, y08) =
   f07
   y01
   (f06
   x2
   (f05
   x1
   y01
   (f04
   (f03
   y02
   ...

Best regards, Brian.
--
http://www.metamilk.com 


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


Re: [Haskell-cafe] Re: Versioning

2006-12-21 Thread Brian Hulley

Lennart Augustsson wrote:

On Dec 21, 2006, at 15:53 , Neil Mitchell wrote:


Hi


there are really no choices for real development. many libraries,
language
extensions and techniques are for ghc only


I develop everything in Hugs, including the Yhc compiler itself. Hugs
is great. There are lots of extensions in GHC, but Haskell 98 is a
perfectly useable language!



I must second this opinion.  There's this (false) perception that you
need all
kinds of extensions to make Haskell usable.  It's simply not true.
Certain
extensions can make your life easier, but that's it.


Well, FingerTrees for example, require MPTCs as in

   pushL :: Measured v a = a - FingerTree v a - FingerTree v a

For any kind of object oriented programming you need existentials to 
separate the interface from the different concrete objects. Also in the code 
I've written I've often needed higher rank polymorphism and scoped type 
variables. Sure it's possible to use all kinds of horrific hacks to try and 
avoid the need for scoped type variables etc but why would anyone waste 
their time writing difficult obfuscated code when GHC has the perfect 
solution all ready to use.


In other words, what on earth is good about gluing oneself to Haskell98? 
Life's moved on...


Best regards, Brian.
--
http://www.metamilk.com 


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


Re: [Haskell-cafe] Re: Versioning

2006-12-21 Thread Brian Hulley

Neil Mitchell wrote:

Hi


In other words, what on earth is good about gluing oneself to
Haskell98? Life's moved on...


If you stick to Haskell 98 you can:

* Convert your code to Clean (Hacle)
* Debug it (Hat)
* Run it in your browser (ycr2js)
* Document it (Haddock)
* Make a cross platform binary (yhc)
* Get automatic suggestions (Dr Haskell)
...

Sometimes you need a type extension, but if you don't, you do get
benefits.


True, though it would be even better if the usual extensions were more 
widely supported, though I suppose identifying what's useful and therefore 
worth supporting is the point of the Haskell Prime process.


As an aside I've often thought it would be better if the various components 
of Haskell compilers/tools would be separated out so that people could 
effectively build their own compiler tailored more specifically for their 
needs. Ie lots of smaller projects each dealing with a particular phase of 
Haskell processing which would be joined together by standard APIs, so that 
someone could use the latest type system extensions with whole program 
optimization while someone else could use those same type extensions with a 
back end designed for graphical debugging etc, and also so that people just 
interested in developing whole program optimization (for example) wouldn't 
have to reinvent the ever-more-difficult wheel of 
lexing/parsing/typechecking/targeting  multiple platforms...


Best regards, Brian.
--
http://www.metamilk.com 


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


Re: Stronger static types, was Re: [Haskell-cafe] Re: Versioning

2006-12-21 Thread Brian Hulley

Jacques Carette wrote:

Yes, dependent types have a lot to do with all this.  And I am an
eager lurker of all this Epigram.


Would it be possible to augment Haskell's type system so that it was the 
same as that used in Epigram?
Epigram itself uses a novel 2d layout and a novel way of writing programs 
(by creating a proof interactively) but these seem orthogonal to the actual 
type system itself.


Also, typing is not the only issue for compile time guarantees. Consider:

   data Dir = Left | Right | Up | Down deriving Eq

   -- Compiler can check the function is total
   foo :: Dir - String
   foo Left = Horizontal
   foo Right = Horizontal
   foo Up = Vertical
   foo Down = Vertical

versus

   -- Less verbose but compiler can't look inside guards
   foo x | x == Left || x == Right = Horizontal
   foo x | x == Up || x == Down = Vertical

versus something like:

   foo (Left || Right) = ...
   foo (Up || Down) = ...

Brian.
--
http://www.metamilk.com 


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


Re: [Haskell-cafe] Shrinking the Prelude: The categorical approach

2006-12-20 Thread Brian Hulley

Imam Tashdid ul Alam wrote:

hi guys,
I was just wondering if anyone is interested is a
quasi-project of rewriting the Prelude (only
shrinking it as measured by the total number of names
imported, read along...)
the idea is (just to be substantially different in
approach) to develop an alternate history of
Haskell.
take map for example, and fmap, I don't think they
should be named different (fmap is ugly, not
suggestive, and conceptually the same).
mplus could be renamed (++) (they are conceptually the
same


I suggest that all functions in classes be given actual names and ASCII 
symbolic names could be defined outside the class as an additional 
convenience eg:


   class Monad m = MonadPlus m where
   mzero :: m a
   mplus :: m a - m a - m a

   (++) = mplus-- 'convenience' name

I think people forget that ASCII symbol names which look intuitive to them 
when they are writing a library or paper, can be very confusing for people 
who need to use many libraries (with consequent explosion of obfuscatory 
symbols) in a project, look terrible when qualified, and make code difficult 
to read because of the need to find/remember precedences and associativity. 
(Note that Haddock does *not* supply this info, you need to look at the 
actual source code of the library to find it out.)



, mzero looks odd, name it empty, or simply zero)


What about (mempty) from Monoid or (empty) from Data.Sequence or 
Control.Applicative? Either these are in some way the same thing as mzero, 
or else they are different in which case either qualified imports would be 
needed everywhere (not necessarily a bad thing) or different names like the 
ones we already have, are needed.



although I think concat should be replaced by msum (or
the other way around preferably :) ? msum is a bad
name) I am somewhat confused by join. concat seems to
match join's type but I don't think the ideas
coincide.
and so on. in particular, we would want:
* no backwards compatibility. the Prelude as is it, is
good enough. we are defining a new module.


Starting with a clean slate seems a good idea, especially to get rid of 
lispy names like (cons), (snoc), (null) and replace them with something 
self-explanatory like (pushL), (pushR), (isEmpty).



* clean categorical hierarchy of type classes
(category theorists wanted!) promoting uniformity.


This would be great. However it is a question to me whether it is even 
possible to organize everything in a single hierarchy. Eg look at the 
problems with trying to reorganize Num, or standard OOP problems with 
hierarchies in general. Since there are multiple ways of looking at a 
domain, it is likely there will need to be multiple hierarchies which will 
probably not interact so well.



* cleaner names. foldl1 means nothing. absolutely
nothing. what's the 1 for?


A while back I suggested using capital letters for suffix to distinguish the 
functionality (fold) from the variant (L == left). Perhaps (foldl1) could be 
renamed (foldLN) ie fold + left + non-empty or (foldLO) for fold + left + 
occupied.



* our Prelude only contains typeclasses, datatypes,
and functions of utmost conceptual (and semantic, such
as error, undefined and seq) importance, everything
else goes to other modules. our Prelude is not going
to be a place for convenient declarations.
* the suffix method of naming (liftM2) is considered
messy. we would prefer a seperate module (promoting
qualified import).


In the particular case of *M functions, I quite like the existing naming 
since it's clear that it's a monadic function. However I'd agree that names 
like (newIORef) are an abomination, that should be replaced by (Ref.new).



this is a fun project. we will not rewrite the
Prelude, we'll merely rename it. I would suggest the
name TheOtherPrelude to make our intentions clear. the
conveniences (like concatMap) goes to
TheOtherPrelude.Extension. I suggest we do it on the
wiki. anyone interested just open a page with your
name of choice. I am not doing it only because there's
no point doing it if no one's interested.


Good luck with this. For my own project, I re-implemented FingerTree's so I 
could use my preferred naming style (and also as an exercise following the 
excellent tutorial-style FingerTree paper), and wrote some trivial wrappers 
for a few other modules eg Data.IORef, Data.Unique so that I could use 
Ref.new, Unique.new etc.I think it would be quite a big task to refactor the 
entire code base according to a clean hierarchy of type classes, and also a 
task I can't really help with since I'm not familiar enough with category 
theory at present, but certainly it would be a worthwhile endeavour imho,


Brian.
--
http://www.metamilk.com 


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


Re: [Haskell-cafe] Haskell Side Effect

2006-12-20 Thread Brian Hulley

Ashley Yakeley wrote:

Since learning Haskell, I can now count in Spanish! See:

  one in Spanish,
  two in Spanish,
  three in Spanish,
  four in Spanish..


Is there a solution ie some concept C such that C Haskell  C Spanish, 
somewhere?

Thanks, Brian.
--
http://www.metamilk.com 


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


Re: [Haskell-cafe] Class annotation on datatype ineffective in function

2006-12-19 Thread Brian Hulley

Reto Kramer wrote:

The code below does not compile unless the bar function is
annotated with a suitable constraint on the class of the formal
parameter.


class (C a)
data (C foo) = XY foo = X foo | Y foo

bar :: a - XY a
bar aFoo = X aFoo


As suggested, this works:


bar :: (C a) = a - XY a


Can someone explain to me why the compiler can not infer that a (in
bar) must be (C a) from the bar result type XY a (by way of the C
class provided for the datatype)?


Hi Reto -
If you'd not given any signature at all the compiler would have inferred the 
correct type for bar, but since you gave an explicit signature, the compiler 
had no option but to complain that you missed out the C a constraint. (ie if 
you decide to provide a signature you must give the full signature including 
constraints since the compiler won't add anything to them - partial 
signatures are not (yet) supported)


Regards, Brian.
--
http://www.metamilk.com 


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


Re: [Haskell-cafe] Showing the 1 element tuple

2006-12-19 Thread Brian Hulley

Neil Mitchell wrote:

Hi,

A weird question, what does the 1 element tuple look like?

() -- 0 element tuple
(,) a b -- 2 element tuple
(,,) a b c -- 3 element tuple

() a - meaningless
(a) - a in brackets

GHC has the 1 element unboxed tuple, (# a #), and all the other sizes
unboxed as well, but how would you visually represent the 1 element
boxed tuple?


Tuples represent dimensionality therefore a 1-element tuple is just a 
1-dimensional value ie the value itself hence a == (a) == ((a)) == (((a))) 
== ...


Brian.
--
http://www.metamilk.com 


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


[Haskell-cafe] Re: [Haskell] ANNOUNCE: Phooey -- a Functional UI library for Haskell

2006-12-12 Thread Brian Hulley

Brian Hulley wrote:

Conal Elliott wrote:


GUIs are usually programmed in an unnatural style, in that ...


Also, suppose you have a gui consisting of an edit widget such that
when the user types something it gets lexed, parsed, and fontified as
a Haskell program, ie from the user's point of view the widget
maintains a syntax highlighted view of the code which is
continuously updated. Would your system do the lexing/parsing for
every key that was pressed or only once, when the widget needs to be
re-rendered (a typical gui for Windows would only propagate changes
and re-draw the gui (ie lex/parse/fontify) when there are no event
messages pending)?


Thinking about this more, a better example would be a gui with 2 widgets: an 
edit widget to type in code and a list widget which displays a list of top 
level functions defined in that code. (The code could be Haskell or some 
simple toy language.)
Then the question becomes: how to set things up such that the code in the 
edit widget is only parsed when the list widget (and/or edit widget) is 
asked to render it's contents rather than every time the user presses a key. 
I think perhaps the problem would be solved by the edit widget passing a 
lazy parse tree (ie an expression evaluating to the parse tree) to the list 
widget.


But an interesting thing is if you compare this to imperative guis, in the 
functional gui each widget passes lazy expressions eagerly whereas in 
imperative guis each widget passes eagerly evaluated expressions lazily ie 
functional is push messages whereas imperative is pull changes when I'm 
asked to pick or render something etc and I'm dirty. (Have I got this 
wrong?)


I imagine that the overhead of eager passing in the functional gui is a 
small price to pay for the ease of using a functional gui, since the 
important thing is that in both guis, the hard work of parsing the code in 
the edit buffer would only be done on demand, unless I'm much mistaken.


If you're still thinking of examples for your paper it would also be really 
great to see how you'd create a widget that displays the result of another 
process (eg a window that displays the output as ghc compiles a program) or 
some other example of how to use the IO monad inside a widget for those 
unfamiliar with combining arrows with monads.


It would also be useful to know more about the relationship between the 
functional gui and WxWidgets to see what characteristics an imperative gui 
toolkit must have in order to be usable with it. (Like the extremely useful 
discussion of low level details in the Fudgets thesis.)


Best regards, Brian.
--
http://www.metamilk.com 


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


Re: [Haskell-cafe] Re: Aim Of Haskell

2006-12-12 Thread Brian Hulley

Kirsten Chevalier wrote:

since it's not as if anyone programs in Pascal anymore.


Yet I'm sure most people who did a computer science degree some decades ago 
remember the old joke about passing things by name or value for what it's 
Wirth... :-)


Brian.
--
http://www.metamilk.com 


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


Re: [Haskell-cafe] Functional GUI combinators for arbitrary graphs of components?

2006-12-03 Thread Brian Hulley

Taral wrote:

On 12/1/06, Brian Hulley [EMAIL PROTECTED] wrote:

This problem is so general (ie converting a cyclic graph into an
expression tree such that each node appears no more than once) that
I'm sure someone somewhere must already have determined whether or
not there can be a solution, though I don't know where to look or
what to search for.


I suggest you check the Functional Graph Library (FGL). It's shipped
as part of GHC.


Thanks for the suggestion. FGL itself (afaics) doesn't seem to have what I 
was looking for but graph algorithm would be a good place to start 
looking.


Brian.
--
http://www.metamilk.com 


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


Re: [Haskell-cafe] Functional GUI combinators for arbitrary graphs ofcomponents?

2006-12-03 Thread Brian Hulley

Paul Hudak wrote:

Brian Hulley wrote:

Anyway to get to my point, though all this sounds great, I'm
wondering how to construct an arbitrary graph of Fudgets just from a
fixed set of combinators, such that each Fudget (node in the graph)
is only mentioned once in the expression. To simplify the question,


If you consider just Dags, I believe that this question is equivalent
to asking what set of combinators will allow you to create an
arbitrary composition of functions that allow sharing inputs and
returning multiple results.  And I think that one answer to that is
the set of combinators that make up the Arrow class.  If you want to
include recursion (i.e. cycles), then you'd have to throw in
ArrowLoop (although that might only provide a nested form of cycles).
It's in this sense that Fudgets is analogous to Fruit.


Thanks. Actually thinking more about it I've probably missed the point that 
for a compositional GUI there's no need for a general graph, since each 
view/controller of the underlying model could be encapsulated as a single 
widget (eg fudget or signal transformer) which could be connected to the 
model via a loop which exposes only the model (thus allowing other views to 
be added later).


Brian.
--
http://www.metamilk.com 


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


Re: [Haskell-cafe] Strange type behavior in GHCi 6.4.2

2006-12-02 Thread Brian Hulley

Grady Lemoine wrote:

f x = x^3



f' = snd . (evalDeriv f)


When I load this in GHCi, I get:

*Main :t f
f :: (Num a) = a - a
*Main :t snd . (evalDeriv f)
snd . (evalDeriv f) :: (Num a, Num (Dual a)) = a - a
*Main :t f'
f' :: Integer - Integer

Why is the type of f' Integer - Integer, especially when the type of
the expression it's defined as is more general?  Is this something I'm
not understanding about Haskell, or is it more to do with GHC 6.4.2
specifically?


This is the monomorphism restriction, which basically says that any binding 
which just has a single variable on the left of the '=' is artificially 
forced to be monomorphic (unless you've given it an explicit type signature) 
eg:


   f = \x - x + 1-- Integer - Integer

whereas

   f x = x + 1-- Num a = a - a

The reason for this is that if you have something like:

   let x = e in (x,x)

you often expect the expression (e) to be evaluated at most once, and shared 
by the two components of the tuple. However if there were no monomorphism 
restriction, then (x) could be polymorphic hence (e) would have to be 
evaluated twice (once for each overloading, even if the result tuple is fed 
to another function which expects both elements to have the same type) which 
would make programs run slower than the programmer expected.


I couldn't find any page on the wiki about this, but there's lots of stuff 
scattered around on the web, and endless discussions in the Haskell mailing 
lists which make entertaining reading ;-)


(The MR is controversial - see 
http://hackage.haskell.org/trac/haskell-prime/wiki/MonomorphismRestriction 
for the latest on what might happen to it in future versions of Haskell.)


Brian.
--
http://www.metamilk.com 


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


[Haskell-cafe] Functional GUI combinators for arbitrary graphs of components?

2006-12-01 Thread Brian Hulley

Hi,
I've been looking at the Fudgets research 
(http://www.cs.chalmers.se/ComputingScience/Research/Functional/Fudgets/ ) 
as an example of a purely functional gui.


Afaiu a brief summary is that a Fudget can represent a GUI widget or some 
other object, which can have some internal state, and which receives and 
passes messages to the other Fudgets it is connected to. Fudgets are 
connected to each other by combinators eg:


   second == first-- sequential (first sends messages to second)
   a * b   -- parallel

There is a continuation passing implementation such that the messages are 
passed and internal states of Fudgets are updated (by replacing each fudget 
with an updated fudget) as these expressions are evaluated hence the message 
passing and maintenance of state doesn't involve any IORefs though 
interaction with external devices such as the OS uses IO.


Anyway to get to my point, though all this sounds great, I'm wondering how 
to construct an arbitrary graph of Fudgets just from a fixed set of 
combinators, such that each Fudget (node in the graph) is only mentioned 
once in the expression. To simplify the question, assume we have the 
following data structure to describe the desired graph:


   data LinkDesc a
   = Series a a
   | Broadcast a [a]
   | Merge [a] a

   type GraphDesc a = [LinkDesc a]

and a function to compute a combined object (eg Fudget) corresponding to an 
arbitrary graph would be:


   mkObj :: Ord label = Map label Obj - GraphDesc label - Obj
   mkObj = -- ???

The result of mkObj will be some expression, composed from a finite set of 
combinators applied to the named objects, but with the all important 
property that each named object appears no more than once in the expression 
(this is what allows Fudgets to correspond to notional objects which 
maintain internal state - during evaluation each fudget gets replaced by an 
updated fudget hence can only appear once in the whole expression).


As a very simple example using existing Fudgets combinators,

   type Map label value = [(label, value)]

   mkObj [(A, objA), (B, objB), (C, objC)]
   [Series A B, Series B C]

   ===objC == objB == objA

and

   mkObj [(A, objA), (B, objB), (C, objC)]
   [Broadcast A [B, C]]

   === (objB * objC) == objA

However:

   mkObj [(A, objA), (B, objB), (C, objC), (D, objD)]
   [Broadcast A [B, C], Series B D, Series A D]

   === ???

The Fudgets library provides many combinators eg for looping, but even so, I 
don't think there are sufficient combinators to express the above graph 
(though possibly extra nodes and tagging/untagging would solve this 
example), or more heavily connected graphs such as:


   [Series A B, Series B C, Series C D, Series D B, 
Series C A]


This problem is so general (ie converting a cyclic graph into an expression 
tree such that each node appears no more than once) that I'm sure someone 
somewhere must already have determined whether or not there can be a 
solution, though I don't know where to look or what to search for.


Any ideas?
Thanks, Brian.
--
http://www.metamilk.com 


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


Re: [Haskell-cafe] Functional GUI combinators for arbitrary graphs ofcomponents?

2006-12-01 Thread Brian Hulley

Brian Hulley wrote:

Anyway to get to my point, though all this sounds great, I'm
wondering how to construct an arbitrary graph of Fudgets just from a
fixed set of combinators, such that each Fudget (node in the graph)
is only mentioned once in the expression. To simplify the question,
assume we have the following data structure to describe the desired
graph:
   data LinkDesc a
   = Series a a
   | Broadcast a [a]
   | Merge [a] a

   type GraphDesc a = [LinkDesc a]


The above is more complicated than necessary. The problem can be captured 
by:


   type GraphDesc a = [(a,a)]

Brian.
--
http://www.metamilk.com 


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


Re: [Haskell-cafe] [Haskell] Defining Cg, HLSL style vectors in Haskell

2006-11-28 Thread Brian Hulley

Slavomir Kaslev wrote:

I have to define a couple of float2, float3, float4 Cg, HLSL style
vectors in Haskell. At first I was tempted to make them instances of
Num, Floating, RealFrac, etc. but some of the functions defined in
those classes have no sense for vectors.


I'd suggest that this implies that these classes are not suitable for 
Vectors.



One such example is signum from class Num.

There are several workarounds for this. One may come up with some
meaning for vectors of such functions, for example:

instance Num Float3 where
   .
   signum a | a == Float3 0 0 0 = 0
 | otherwise = 1


This looks a bit unnatural. Also, testing equality of Floats is not 
generally recommended.




[snip]
I know that I can scrap all those Num, Floating, RealFrac, etc.
classes and define class Vector from scratch, but I really don't want
to come up and use different names for +, -, etc. that will bloat the
code.


While it may be tempting to want to use symbolic operators like + and -, 
these quickly become very confusing when more distinctions need to be made 
(eg between cross product, dot product, and scaling, or between transforming 
a position versus transforming a direction) so I'd argue that for 
readability descriptive names are better than symbols:


   class Num a = Vector v a where
   plus :: v a - v a - v a
   minus :: v a - v a - v a
   cross :: v a - v a - v a
   dot :: v a - v a - a
   scale :: a - v a - v a
   magSquared :: v a - a

   class Num a = Transform mat vec a where
   transformPosition :: mat a - vec a - vec a
   transformDirection :: mat a - vec a - vec a

   instance Num a = Transform Mat44 Vec4 a where
   -- ...

If you're doing matrix transformations, you might also like to consider 
using separate PositionN and DirectionN types instead of VecN to make use of 
the type system to catch some math bugs but I haven't looked into this 
myself yet so I don't know whether this would be practical or not.


Best regards,
Brian.
--
http://www.metamilk.com 


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


[Haskell-cafe] Why instances can't be hidden (was: non-total operator precedence order)

2006-11-11 Thread Brian Hulley

Benjamin Franksen wrote:

Henning Thielemann wrote:

On Fri, 10 Nov 2006, Benjamin Franksen wrote:

Although one could view this as a bug in the offending module it
makes me somewhat uneasy that one additional import can have such a
drastic effect on the code in a module /even if you don't use
anything from that module/.


It's the same as with instance declarations, isn't it? I don't want
to defend the problems arising with todays anonymous instance
declarations,


Right. However, with instances I can imagine solutions that avoid
naming them, that is, I could imagine to write something like

 select instance C T1 T2 ... Tn from module M

or

 import M hiding (instance C T1 T2 ... Tn, )

Such a feature could prove extremely useful in practice.

Disclaimer: I am almost sure that there is something I have
overlooked that makes such a simple solution impossible, otherwise it
would have been proposed and implemented long ago...


I think the reason you can't do this kind of thing is that within any set of 
modules that is compiled at the same time, anywhere in any of these modules, 
if you have a type T that's an instance of class C, then all occurrences of 
C T must refer to the exact same instance declaration or else things would 
get totally messed up when/if the compiler did whole program optimization.
In other words, the instances are actually properties of the type(s) 
themselves so allowing different modules to see different implementations 
of the instances would break the conceptual merging of modules (modulo 
renaming) that occurs at compile time.


Regards, Brian.
--
Logic empowers us and Love gives us purpose.
Yet still phantoms restless for eras long past,
congealed in the present in unthought forms,
strive mightily unseen to destroy us.

http://www.metamilk.com 


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


Re: [Haskell-cafe] Automatic fixity allocation for symbolic operators

2006-10-15 Thread Brian Hulley

Jim Apple wrote:

On 10/14/06, Brian Hulley [EMAIL PROTECTED] wrote:

User defined fixities are an enormous problem for
an interactive editor


This is the second or third time you've proposed a language change
based on the editor you're writing. I don't think this is a fruitful
avenue.



Bertram Felgenhauer wrote:

Brian Hulley wrote:

   infixr 9  .!!   99.9

Ouch.

As far as editors go I have little sympathy.



Nicolas Frisby wrote:

I think it's unreasonable to tie programmers' hands for the sake of
off-loading rather trivial tasks to editors.



J. Garrett Morris wrote:

On 10/14/06, Nicolas Frisby [EMAIL PROTECTED] wrote:

Perhaps the editor could assume a default precedence ...

I agree that changing the language in such an unintuitive way -
breaking existing code in the process - to suit an editor is
counterproductive and ridiculous.



I feel that the example I used of an interactive editor has somewhat 
eclipsed the purpose of my post, which was basically to see if there is some 
way to arrive at an agreed association of operator precedences with symbolic 
ops such that this would include the current Prelude operators and have some 
kind of intuitive extension to all other possible symbolic ops which would 
respect one's expectations that * and + should be similar to * and + in 
terms of relative precedence and absolute associativity. After all, if a 
library writer decided to make * bind more loosely than + one might 
justifiably be frustrated at the apparent inconsistency therefore why not 
just make all this systematic and fixed down to remove these problems?


I had thought perhaps someone might have already made such a global 
operator table suitable for functional programming, or some suitable 
algorithm hence the inclusion of my first stumbling attempt at one to try 
and set the ball rolling and at least save someone else several hours of 
hard work going down the same dead end if such it is.


Jim Apple wrote:


There are three ways to change Haskell's lexical structure:

1. DIY on an open-source compiler/interpreter of your choice.
2. Write your own compiler/interpreter.
3. Get the change into Haskell''.

If the Haskell'' procedure is like the Haskell' procedure, you'll have
to do 1 or 2 before you do 3.

It's possible that you will convince someone that your syntax changes
are worth doing, and that this person will do step 1 or step 2 for
you, but I don't think so. I haven't done the research myself, but I
think if you look at the source control logs for Your Favorite Haskell
Compiler/interpreter and the HCAR, you will find very few
commits/projects devoted to syntax. I think this is because Haskellers
are much more interested in semantics.


Afaiu the whole concept of type classes arose because of the desire to avoid 
having to think up different names for related functions and MPTCs were 
suggested by the syntax for single parameter TCs (though I can't remember 
the reference where I think I remember reading this latter point).




Proposing changes that break existing code or segment the Haskell code
base just doesn't seem like a win.


Since all syntactic and many semantic changes necessarily break existing 
code or segment the code base this would seem to imply that the language 
should not be changed at all or that everything must be backwards 
compatible, so that we have to drag the Achilles heel of original mistakes 
around for all eternity. I'd have thought a solution would be to just use a 
tool to automatically convert existing code to whatever new syntax is found 
to be better, thus allowing the language to be gradually perfected as more 
and more issues are brought to light.


Still I agree with you that a more sensible approach in terms of someone 
like me writing an editor is simply for me to take Haskell as an inspiration 
and incorporate my ideas in it so that any changes can later be seen in 
relation to a (hopefully facilitated and enjoyable) programming experience 
rather than trying to share my ideas piecemeal and insufficiently 
contextualized as they arise.


Thanks to all who replied,
Brian.
--
Logic empowers us and Love gives us purpose.
Yet still phantoms restless for eras long past,
congealed in the present in unthought forms,
strive mightily unseen to destroy us.

http://www.metamilk.com 


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


[Haskell-cafe] Automatic fixity allocation for symbolic operators

2006-10-14 Thread Brian Hulley

Hi -
I'm wondering if it is possible to construct a methodical procedure to 
assign a fixity to symbolic operators so that we could get rid of the need 
for user defined fixites. User defined fixities are an enormous problem for 
an interactive editor, because it is not possible to construct a parse tree 
of some code if you don't know what the fixities are, and an editor must be 
able to do something useful with a code fragment without having to look 
inside other modules (because the other modules may not yet have even been 
written!). Also, the programmer or reader of code needs to be able to 
understand each code fragment independently as well.



From the Haskell98 report, the Prelude defines:


   infixr 9  ., !!
   infixr 8  ^, ^^, **
   infixl 7  *, /, `quot`, `rem`, `div`, `mod`
   infixl 6  +, -
   infixr 5  :, ++
   infix  4  ==, /=, , =, =, 
   infixr 3  
   infixr 2  ||
   infixl 1  , =
   infixr 1  =
   infixr 0  $, $!, `seq`

Suppose we ignore the varid operators and just consider the symbolic ops. 
What I'm trying to find is a systematic way to assign fixities to all other 
possible sequences of symbol characters that is consistent with what we've 
already got in the Prelude.


As a first step, we could say that mirrored operators must share the same 
precedence ie:


   ==


For associativity, we could assign each character an associativity weight:

   -1  left associative
   0neutral
   1right associative

and say that the associativity is simply the sign of the sum of the 
associativity weights of the characters thus:


  -1
   =0
   1

   =0 + 1 + 1ie infixr

Note that I don't care about non-associative ops since the non-associativity 
of something should be a question for the type checker not the parser imho - 
ideally we should be able to create a parse tree for any possible operator 
expression.


To form the precedence, we could assign each character a precedence value 
eg:


   9 .!
   8^
   7*/
   6+-
   5:
   4=
   3
   2|
   1
   0$

A first attempt might be to say that the precedence is simply the decimal 
expansion of the precedence values eg = has precedence 1.14 and $! has 
precedence 0.9. However, as noted above, mirrored ops must share the same 
precedence so an alternative is to create some ordering of characters such 
that when the set of characters in an operator is sorted according to this 
ordering, the decimal expansion of the precedence digits will give the same 
relative ordering for operator precedences as the Prelude.


For example, using $ |  + - * / ^ . ! :   = as the ordering, we'd get:

   infixr 9  .!!   99.9
   infixr 8  ^, ^^, **8   8.87.7
   infixl 7  *, /,77
   infixl 6  +, -6 6
   infixr 5  : , ++ 56.6
   infix  4  ==, /=, , =, =,   4.4   7.4   11.41.41
   infixr 3  3.3
   infixr 2  ||2.2
   infixl 1  , =1.11.14
   infixr 1  =1.14
   infixr 0  $, $!00.9

Although most existing ops get a similar precedence (eg ^ ^^ and ** are all 
still in the same group relative to the other ops despite the fact that 
within the group there is now an ordering) the main problem seems to be that 
 = =  get precedences that bind too loosely and /= is totally wrong.


This problem aside, the above algorithm would give sensible precedences for 
such things as:


   ::   5.1
   +*6.116.11

where the use of  neutralizes the associativity contribution of  or  
respectively (since (-1) + 1 == 0), giving us the intuitive associativity 
we'd expect from the interesting character in the middle.


(The problem of /= getting 7.4 could be solved by putting / after = in the 
order, to get 4.7, but unfortunately this would mean that since  must be 
before =,  would be before / so / would get the wrong precedence 
compared to *)


Another issue is that there is no assignment of associativity weights such 
that * is infixl but ** is infixr (ditto + and ++) so perhaps we'd need 
to associate each character with an associativity function. Similar to 
precedences, we then define an associativity ordering and let the resulting 
associativity be the sign of the composition of the sorted functions applied 
to 1 eg:


   ^  const (-1)
   *  \x - x * (-1)
   =  id
const (-1)
 (+1)
 (+ (-1))

Then
   *(\x - x * (-1)) 1===-1 ie left
   **  (\x - x * (-1)) . (\x - x * (-1)) $ 1 === +1 ie right

   =
   =
   (+ (-1)) . (+ (-1))  .   id$ 1 === -1

   *-- remember ordering

Re: [Haskell-cafe] A type in search of a name...

2006-10-13 Thread Brian Hulley

Albert Lai wrote:

Brian Hulley [EMAIL PROTECTED] writes:


You'll never believe it but I've been struggling last night and all
of today to try and think up a name for the following type and I'm
still nowhere near a solution:

data ??? = VarId | VarSym | ConId | ConSym


Perhaps Atom.


Thanks for the suggestion,
Brian.
--
Logic empowers us and Love gives us purpose.
Yet still phantoms restless for eras long past,
congealed in the present in unthought forms,
strive mightily unseen to destroy us.

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


Re: [Haskell-cafe] Vertical tabs in source code and other obscure chars

2006-10-11 Thread Brian Hulley

Brian Hulley wrote:

Hi,
In the Haskell98 report at
http://haskell.org/onlinereport/lexemes.html section 2.2 has the rule:

   whitechar - newline | vertab | space | tab | uniWhite

Does anyone know what a vertical tab is supposed to do?
Is there any reason to allow them as whitespace? (Does anyone in the
universe actually use them?)


To rephrase my question, what is a Haskell lexer/parser supposed to do when 
it encounters a vertical tab? The description of the layout rule in the 
report does not specify what a vertical tab means.


If no-one knows the answer, perhaps the rule should be changed to:

   whitechar - newline | space | tab | uniWhite

and a vertical tab's could just be treated as illegal characters.

Regards, Brian.
--
Logic empowers us and Love gives us purpose.
Yet still phantoms restless for eras long past,
congealed in the present in unthought forms,
strive mightily unseen to destroy us.

http://www.metamilk.com 


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


[Haskell-cafe] A type in search of a name...

2006-10-10 Thread Brian Hulley

Hi,
You'll never believe it but I've been struggling last night and all of today 
to try and think up a name for the following type and I'm still nowhere near 
a solution:


   data ??? = VarId | VarSym | ConId | ConSym

this is part of a type to describe Haskell lexemes:

   data Token = TName !??? !ByteString.T | ...

Here are some of my attempts to fill in ??? and my reasons for rejecting 
them:


1) VarConIdSym - the problem is that it's too long and the first letter is 
'v' which could be confused with the letter 'V' in VarId or VarSym


2) Name - the problem is that this suggests the string itself rather than 
the VarId/VarSym/ConId/ConSym'ness of the token


3) NameType - I'm trying to avoid using the words Type Kind etc because 
I'll probably want to use these later for other things and in any case 
NameType suggests the type of a lexical name ie Token itself


4) Space - this can be confused with something to represent whitespace or 
the namespaces introduced by modules


5) Just using data Token = TVarId !BS.T | TVarSym !BS.T | ... -- explodes 
into too many different cases when you add tokens for qualified names and 
all their variations (since I'm also representing incomplete tokens like 
Foo. and Foo.where (as a prefix of Foo.whereas etc since it can't 
stand by itself because where is a reserved word))


6) Using Bool as in data Token = TName !Bool !Bool !BS.T -- problem is that 
then I won't get any help from the typechecker if I accidentally confuse the 
order of Bools when matching etc. I could use the record syntax but then 
code can become very clunky to look at and it would still allow the Bools to 
get confused when they are passed about


Any ideas? I must say that trying to think up names for things is absolutely 
the most difficult task in programming imho. The problem is that once fixed 
down, a name gets used all over the place and becomes totally entrenched in 
the code and affects how one thinks about the code thereby influencing its 
whole future development in a very deep and pervasive way (think suffixes/ 
prefixes/ relationships with other concepts etc).


I would also be satisfied with just good names for the following types:

   data ???1 = Var | Con
   data ???2 = Id | Sym
   data ???3 = Op | Plain

(I just combined ???1 and ???2 in ??? to try and save some space in the 
representation but ideally they would be separate types if only there were a 
way to tell the compiler to represent each by 1 bit in a word at the machine 
level like C's struct {VarCon vc : 1; IdSym is : 1;})


Any suggestions welcome,
Thanks, Brian.
--
Logic empowers us and Love gives us purpose.
Yet still phantoms restless for eras long past,
congealed in the present in unthought forms,
strive mightily unseen to destroy us.

http://www.metamilk.com 


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


[Haskell-cafe] Vertical tabs in source code and other obscure chars

2006-10-09 Thread Brian Hulley

Hi,
In the Haskell98 report at http://haskell.org/onlinereport/lexemes.html 
section 2.2 has the rule:


   whitechar - newline | vertab | space | tab | uniWhite

Does anyone know what a vertical tab is supposed to do?
Is there any reason to allow them as whitespace? (Does anyone in the 
universe actually use them?)


Thanks, Brian.
--
Logic empowers us and Love gives us purpose.
Yet still phantoms restless for eras long past,
congealed in the present in unthought forms,
strive mightily unseen to destroy us.

http://www.metamilk.com 


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


Re: [Haskell-cafe] Haskell performance (again)!

2006-10-09 Thread Brian Hulley

Lennart Augustsson wrote:

I think your first try looks good.

[snip]

...
addPoly1 p1@(p1h@(Nom p1c p1d):p1t) p2@(p2h@(Nom p2c p2d):p2t)
   | p1d == p2d = Nom (p1c + p2c) p1d : addPoly1 p1t p2t
   | p1d  p2d = p1h : addPoly1 p1t p2
   | p1d  p2d = p2h : addPoly1 p1 p2t
...


The last comparison is redundant (this was in the original version too) 
because p1d  p2d is implied (certainly for this case where p1d, p2d::Int) 
by the fall through from not satisfying == and  so how about:


   addPoly1 p1@(p1h@(Nom p1c p1d):p1t) p2@(p2h@(Nom p2c p2d):p2t)
   | p1d == p2d = Nom (p1c + p2c) p1d : addPoly1 p1t p2t
   | p1d  p2d = p1h : addPoly1 p1t p2
   | otherwise = p2h : addPoly1 p1 p2t

Regards, Brian.
--
Logic empowers us and Love gives us purpose.
Yet still phantoms restless for eras long past,
congealed in the present in unthought forms,
strive mightily unseen to destroy us.

http://www.metamilk.com 


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


Re: [Haskell-cafe] Either as a Monad instance

2006-10-03 Thread Brian Hulley

Ross Paterson wrote:

On Tue, Oct 03, 2006 at 07:52:54AM -0400, Lennart Augustsson wrote:

Yes, having fail in the Monad is a horrible wart.


(As far as I know, it's there for the translation of pattern match
failure in do-expressions.)


I think it would be much less of a wart if the signature for fail was just:

   fail :: m a

because what's the point of the String argument anyway (other than trying to 
hack a kind of half-baked debug facility into the language)?


Regards, Brian.
--
Logic empowers us and Love gives us purpose.
Yet still phantoms restless for eras long past,
congealed in the present in unthought forms,
strive mightily unseen to destroy us.

http://www.metamilk.com 


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


Re: [Haskell-cafe] smallest double eps

2006-09-30 Thread Brian Hulley

Lennart Augustsson wrote:

Hang on, hang on, now I'm getting confused.

First you asked for the smallest (positive) x such that
   1+x /= x
which is around x=4.5e15.


1 + 0 /= 0

0 is smaller than 4.5e15

So I don't understand this at all...

Regards, Brian.
--
Logic empowers us and Love gives us purpose.
Yet still phantoms restless for eras long past,
congealed in the present in unthought forms,
strive mightily unseen to destroy us.

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


Re: [Haskell-cafe] smallest double eps

2006-09-30 Thread Brian Hulley

Thomas Davie wrote:

On 30 Sep 2006, at 17:19, Brian Hulley wrote:


Lennart Augustsson wrote:

Hang on, hang on, now I'm getting confused.
First you asked for the smallest (positive) x such that
   1+x /= x
which is around x=4.5e15.


1 + 0 /= 0

0 is smaller than 4.5e15

So I don't understand this at all...


But then 0 isn't positive.


Why not?
In any case every positive number nust satisfy the above inequation so what 
about 0.1, which is certainly smaller than 4500?


Regards, Brian.
--
Logic empowers us and Love gives us purpose.
Yet still phantoms restless for eras long past,
congealed in the present in unthought forms,
strive mightily unseen to destroy us.

http://www.metamilk.com 


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


Re: [Haskell-cafe] Re: A better syntax for qualified operators?

2006-09-29 Thread Brian Hulley

Benjamin Franksen wrote:

Brian Hulley wrote:

ith = Data.Array.IArray.(!)


Sorry, but I can't see the problem here. Why can't the editor offer
the operator as '!' in the list of options, and if the user selects
it insert both '(' and ')' at the right places (i.e. before the
module name and after the operator)? Is there some unwritten law that
forbids editors or IDEs to insert stuff at positions other than the
current cursor position?


I hadn't thought of that - I've now decided to just use the existing syntax 
here.




Generally speaking, I would always hesitate to change the language so
it better suits programming tools(*). It is the tools which should
adapt to the language, even if that means the programmer has to find
new ways of suporting the user (and the language). The most important
reason being that code is more often read than written.


My motivation for the change was that it would better suit the human user of 
the programming tool, though in this particular instance you and Henning 
have convinced me that the original syntax was better after all.




At the danger of becoming completely off-topic now (sorry!), I have
to say that I find /both/ versions ugly and unnecessarily hard to
read. My personal solution is to generally avoid qualified imports.


How does this solution scale? Surely it's only lucky if people happen to 
choose names that don't clash with those of other modules?



I use it only if absolutely necessary to disambiguate some symbol, and
then just for that symbol. I am aware that there is an opposing
faction here, who tries to convinve everyone that qualified import
should be the standard (and the actual exported symbols --at least
some of them-- meaningless, such as 'C' or 'T').


Although C and T are in themselves meaningless, the name of the module 
itself is not. As I understand it, this convention makes the module name 
carry the meaning so you use Set.T instead of Set.Set where the meaning is 
duplicated (a rather uneasy situation) in both the module name and type 
name.



I think such a
convention is inappropriate for a functional language (especially one
with user defined operators). There simply is no natural 1:1
correspondence between data type declaration and functions acting on
that data built into the language, as opposed to e.g. OO languages.
Extensibility in the functional dimension, i.e. the ability to
arbitrarily add functions that operate on some data without having to
change the code (module) that defines the data, is one of the
hallmarks of functional programming, as opposed to OO
programming.


If you have an abstract data type then it *is* like an object (though in a 
potentially more powerful way than in OOP) because there is no other way to 
manipulate values of that type.
If the type is not abstract, the advantage of calling it T is just that it 
avoids naming it twice (by type name and module name) in the situation where 
you want to not worry about name clashes with constructors of other types.



However, nothing prevents us from offering two
interfaces (visible modules), one where the data type is abstract (client
interface) and a different one where it is concrete (extension
interface)


You can still call both types T... :-)

Regards, Brian.
--
Logic empowers us and Love gives us purpose.
Yet still phantoms restless for eras long past,
congealed in the present in unthought forms,
strive mightily unseen to destroy us.

http://www.metamilk.com 


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


Re: [Haskell-cafe] A better syntax for qualified operators?

2006-09-28 Thread Brian Hulley

Brandon Moore wrote:

Brian Hulley wrote:

I would *like* to be able to use the syntax:
   ith = Data.Array.IArray.(!)


Why does the nice argument not apply equally well to infixifying
things? Shouldn't I be able to write

myArr Data.Arr.`get` ix


Good point. This would also remove the need for allowing double conversion 
as in OpIdOp which was an element of asymmetry in my original proposal. Thus 
I revise my proposal to the following:


   varId ::= id
   varOp ::= symbol
   varIdOp ::= ` varId `
   varOpId ::= ( varOp )

   qx ::= {conId .}+ x

so the concerns of qualification and Id, Op, Id-Op would now be separated 
(the point being that you can only make a decision regarding Id-Op when 
you know whether or not you're starting with an Id or an Op and you only 
know this latter fact when you've already arrived at the module by typing 
the qualifier).






(Also the trailing backquote in the existing syntax is redundant)


The trailing backquote is just as redundant as the trailing close
paren in the syntax for using a symbol as a prefix function and just
as important for my comment on backticks as the closing paren is to
your proposal for sections -
it means it's lexically apparent at least at one side of the
identifier that it's a section/infixification


I'm not sure I understand this argument for why a trailing backquote is 
needed, though I can see it would be needed if the dist-fix idea proposed by 
Benjamin Franksen in 
http://www.haskell.org/pipermail/haskell-cafe/2006-August/017373.html was 
adopted eg:


   Control.K.`if cond Control.K.`then` t Control.K.`else` f Control.K.fi`

Regards, Brian.

--
Logic empowers us and Love gives us purpose.
Yet still phantoms restless for eras long past,
congealed in the present in unthought forms,
strive mightily unseen to destroy us.

http://www.metamilk.com 


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


Re: [Haskell-cafe] flip dot

2006-09-28 Thread Brian Hulley

On Thursday, September 28, 2006 1:33 AM, Greg Fitzgerald  wrote:

Since there's talk of removal of the composition operator in 
Haskell-prime,

how about this:

Instead of:
foo = f . g

you write:
foo = .g.f

A leading dot would mean, apply all unnamed parameters
to the function on the right.  A trailing dot would mean,
apply the result of the left to the function on the right.


Hi -

I think the H' proposal 
http://hackage.haskell.org/trac/haskell-prime/wiki/CompositionAsDot is an 
extremely bad idea. I really don't see why people have so many problems with 
the idea of just placing spaces before and after the dot when used as an 
operator, and in any case it's hard to think of a more important operator in 
a functional language than composition and a more fitting symbol for it than 
the simple dot.


Also, the syntax .x with no spaces between the '.' and the 'x' is needed 
for at least one record poposal (eg 
http://www.haskell.org/pipermail/haskell-cafe/2006-August/017466.html)


Regards, Brian.


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


[Haskell-cafe] A better syntax for qualified operators?

2006-09-27 Thread Brian Hulley

Hi -
Consider the scenario when you want to find a function that returns the i'th 
element of an array but all you know is that there is a module called 
Data.Array.IArray that will probably have such a function in it. So you 
start typing in your program:


   let
   ith = Data.Array.IArray.

at this point, you'd hope the editor you're using would somehow display a 
list of avaliable values exported from Data.Array.IArray including the 
indexing function, so you could select it, thus I would *like* to be able to 
use the syntax:


   let
   ith = Data.Array.IArray.(!)

because it's not the user's fault that the person who wrote 
Data.Array.IArray decided to use a symbol instead of an identifier for this 
function - the user of Data.Array.IArray in this case just wants to see 
normal identifiers to use with prefix application so the use of (!) at this 
point effectively gets rid of the unwanted operatorness associated with the 
function.


However the current syntax of Haskell would not allow this. Instead you have 
to write:


   let
   ith = (Data.Array.IArray.!)

The problem is that the user of Data.Array.IArray has to know already in 
advance, before typing the 'D' of Data, that the indexing function has 
been named with a symbol instead of an identifier, but this knowledge is 
only available later, when the user has typed the '.' after IArray, so the 
current syntax would be frustrating for the user because the user then has 
to go all the way back and insert an opening paren before the 'D'.


Also, consider the appearance of:

   let
   ith = (Data.Array.IArray.!) arr i
   b = Data.Array.IArray.bounds arr
vs
   let
   ith = Data.Array.IArray.(!) arr i
   b = Data.Array.IArray.bounds arr

I'm not sure if I've managed to explain this problem clearly enough, but my 
proposal is that we might consider changing the lexical syntax of Haskell as 
follows:


   varId ::= id
   varOp ::= symbol
   varIdOp ::= ` varId
   varOpId ::= ( varOp )
   varOpIdOp ::= ` varOpId

   qvarId ::= {conId .}+ varId-- { }+ denotes 1 or more times
   qvarIdOp ::= ` qvarId
   qvarOp ::= {conId .}+ varOp
   qvarOpId ::= {conId .}+ varOpId
   qvarOpIdOp ::= `qvarOpId

In other words, to turn an operator symbol into an id, the parentheses would 
be put immediately around the symbol (with no spaces since this is lexical 
syntax), and to turn an id into an operator the backquote is put in front of 
the entire (qualified) id.


(Also the trailing backquote in the existing syntax is redundant)

The above syntax would have 3 advantages:
   1) It allows the client of a module to write code without having to 
worry if the author of the module used symbols or identifiers to name 
functions - everything exported from the module can be made to appear as if 
it was named by an identifier (ie OpId)
   2) Moving the parentheses to the lexical syntax makes syntax 
highlighting easier (because there are no comments to worry about inside the 
OpId) and also makes parsing simpler because all the mess associated with 
Ops versus Ids is handled by the lexer

   3) It allows an editor to make a distinction between

   (+)-- an operator turned into an identifier - varOpId
   ( + )  -- an expression with 2 gaps in it which should be 
marked as incomplete

   (+ )   -- a section with 1 gap

Some examples of the proposed syntax are:

   let
   ith = Data.Array.IArray.(!) arr i
   foo = k `Math.(+) 6-- default precendence
   bar = k Math.+ 6-- using precedence of + in module Math

When you try to write an editor for Haskell (or some subset of it), you 
quickly discover these areas of Haskell syntax like the above which need to 
be changed to get an optimum interactive editing experience. I think it *is* 
possible to adjust the Haskell grammar so that it is LL(1) and the only 
reason it is not already LL(1) seems to be that the grammar has been 
designed with compilers (which only need to deal with complete modules) in 
mind rather than programmers interactively editing in mind.


(The other change needed for LL(1) is to give contexts a marker before they 
appear eg:


   foo :: {MonadIO m} a - m a
)

By LL(1) I'm really meaning that the grammar for interactive editing needs 
to be adjusted so that it is possible to maintain the invariant that as code 
is entered from left to right constructs and identifiers can be highlighted 
according to their grammatical role and highlighting (modulo incompleteness) 
must remain unchanged regardless of whatever is typed afterwards to the 
right otherwise it can become more of a liability than a help, hence my hope 
that some future revision of Haskell grammar might consider taking the above 
points into account.


Regards, Brian.
--
Logic empowers us and Love gives us purpose.
Yet still phantoms restless for eras long past,
congealed in the present in unthought forms,
strive mightily unseen to destroy us.


Re: [Haskell-cafe] Writing forum software in Haskell

2006-09-24 Thread Brian Hulley

David House wrote:

Hi all.

The recent thread on email vs. forums inspired a bit of interest to
get some forum software on haskell.org. Were we to go ahead with this,
I think it'd be great to have this software written in Haskell itself.

[snip]

* What kind of forum are we aiming at? In my eyes, it'd be less like
the bloated phpBBs out there full of oversized signatures and avatars,
and more like the minimalistic bbPress on show at, for example, the
WordPress support forums [1].
* What would be a compulsory feature list?


1) I think anyone who posts should first have to register to avoid the 
problem of spam.


2) I think it would be good if it was possible to get away from the usual 
tree structure of posts. By this I mean that usually you have to choose a 
post to reply to, which is awkward if you want to comment on more than one 
previous post because then it's not clear what post to choose as the 
parent.


As a rough idea, perhaps something which considered paragraphs(*) as the 
basic unit of discourse ie


   data Post = Post {_author :: !Author, _time :: !Time, _topic :: !Topic, 
_paras :: ![PostPara]}


   data PostPara = Own !Paragraph | Quoted !PostPara !Author !Time !Topic

   data Paragraph = Text !ByteString | Code !ByteString

and I'd imagine posts being edited using an editor which displayed a 
vertical sequence of PostPara's (ie edit boxes for the paragraphs you've 
written yourself and some other widget involving a static text box to 
display paras that you're quoting)


Multiple consecutive paras that you write yourself would just be written in 
the same edit box. Actually the whole post could be written in one edit box 
if there was a special escape syntax for quoting (you'd select some text in 
some other post then click quote and it would be pasted into the post 
you're composing surrounded by the appropriate escape sequences and source 
info, and like the wiki editor, you could click preview to see how the whole 
thing would look when posted).


This would give full support for DAG based discussions. (At the moment in 
the mailing list if I want to reply to more than one person I have to click 
reply on each email I'm replying to and cut and paste the indented text 
from the second person's email into my reply to the first and hope that I 
don't accidentally send the second blank reply by mistake, and if someone 
has chosen to include a signature with their message or sent it using HTML 
instead of plain text I have to manually indent each individual line myself 
because Outlook Express doesn't display the text of signed messages but 
instead puts it into a file like ATT12.txt...)


(*) Of course the above representation doesn't give any way to only quote 
part of a paragraph or to split paragraphs up so it might be too inflexible. 
It might also not be clear what should be regarded as a paragraph. Perhaps 
span of text would be a better unit of discourse.


3) It would be nice if there was a way to put something in the centre to 
be discussed from different angles, instead of always being stuck with a 
linear flow, where important points made in previous posts can just get 
ignored altogether because they are too far back in linear time. The 
scenario I'm thinking of is:


   3a) Person A makes 2 good points, A1 and A2

   3b) Person B replies to A1

   3c) Person C replies to B's reply of A1

   3d ) Long discussion about A1

   3e) A2 has completely been forgotten and is never addressed

I'm imagining a visual representation of the text in the centre with the 
discussion around it though perhaps this is getting too complicated for 
what's possible just with HTML.


4) Another nice feature would be the ability to just say cool or yes or 
no without having to actually make a real post like a kind of vote for or 
against an idea.


Anyway best of luck with whatever forum people come up with. I originally 
used to post to the mailing list using the Google group fa.haskell (strange 
name!!!) but though I liked the Google interface the posting didn't work 
properly - my posts were delayed several days and sometimes never got there 
at all.


Regards, Brian.
--
Logic empowers us and Love gives us purpose.
Yet still phantoms restless for eras long past,
congealed in the present in unthought forms,
strive mightily unseen to destroy us.

http://www.metamilk.com 


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


Re: [Haskell-cafe] Why am I not allowed to use CStringLen inforeignexport?

2006-09-23 Thread Brian Hulley

Andreas Marth wrote:

low_l :: Word8 = fromIntegral (len .. 0x)
low_h :: Word8 = fromIntegral (shiftR len 8 .. 0x)
high_l :: Word8 = fromIntegral (shiftR len 16 .. 0x)
high_h :: Word8 = fromIntegral (shiftR len 24 .. 0x)


Hi -
I just noticed the mask should be changed to 0xFF for the BSTR8 version 
above.
Also, I'm not actually sure if a mask is needed at all. I just used one to 
make sure there would be no chance of an overflow exception being thrown, 
but the Haskell report doesn't seem to specify anything at all about the 
behaviour of (fromIntegral) when converting between types of different 
sizes.


Perhaps someone on the list can clarify whether or not a mask is needed ie 
is fromIntegral allowed to throw exceptions or does it always just silently 
discard unwanted bits of the argument being converted?


Thanks, Brian.
--
Logic empowers us and Love gives us purpose.
Yet still phantoms restless for eras long past,
congealed in the present in unthought forms,
strive mightily unseen to destroy us.

http://www.metamilk.com 


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


Re: [Haskell-cafe] Why am I not allowed to use CStringLen inforeignexport?

2006-09-22 Thread Brian Hulley

Andreas Marth wrote:

Thanks a lot for this information it helped a lot.


Glad to be of help.


I am thinking about creating a wikipage about Haskell-VBA
interfacing through a DLL.
Is it okay for you if I put your code there?


Yes.


I am a bit concerned about the memory. newArray states that the
memory has to be freed after usage. Is this needed here? How can it
be done?


One way could be to write a function which creates the BSTR, passes it to a 
function, then deallocates the BSTR before returning eg (untested):


   import Control.Exception (bracket)

   withBSTR8 :: [Char] - (BSTR8 - IO a) - IO a
   withBSTR8 s f =
   bracket
   (createBSTR8 s)
   (\bstr - free (bstr `plusPtr` (-4)))
   (\bstr - f bstr)

Regards, Brian.
--
Logic empowers us and Love gives us purpose.
Yet still phantoms restless for eras long past,
congealed in the present in unthought forms,
strive mightily unseen to destroy us.

http://www.metamilk.com 


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


Re: [Haskell-cafe] Re: ambiguous partially defined type problem

2006-09-15 Thread Brian Hulley

Maarten wrote:

Only update (see code below) is a bit ugly (I have no idea why I need
fixCastUpdate)
class (Show a, Typeable a) = ICustom a where

  [snip]

   update :: a - (forall b. (ICustom b) = b - b) - a
   update a f = f a

instance ICustom Node where
   getVal (Node n) f = getVal n f
   update (Node n) f = Node (update n f)

updateM :: forall a b. (ICustom a, ICustom b) = (a - b) -
NodeState () updateM f = do
   s - get
   let s' = update s (fixCastUpdate f)
   put s'


Hi Maarten -
Looking at this again, I wonder if the following changes would work:

   -- this change is not strictly necessary
   update :: a - (a - a) - a

   updateM :: (forall a. ICustom a = a - a) - NodeState ()
   updateM f = do
   s - get
   let s' = update s f
   put s'

I think the reason why fixCastUpdate was needed in your original definition 
of updateM is because the type of f seems to be too general (a-b) compared 
to the type of f in the update method of ICustom (b-b)


Regards, Brian.
--
Logic empowers us and Love gives us purpose.
Yet still phantoms restless for eras long past,
congealed in the present in unthought forms,
strive mightily unseen to destroy us.

http://www.metamilk.com 


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


Re: [Haskell-cafe] Re: ambiguous partially defined type problem

2006-09-15 Thread Brian Hulley

Brian Hulley wrote:

   -- this change is not strictly necessary
   update :: a - (a - a) - a


Sorry - I just looked again at the instance decl for Node, so the above 
change should not be made.


Apologies for the multiple posts, I must try to think more before clicking 
send ;-)


Regards, Brian. 


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


Re: [Haskell-cafe] Why am I not allowed to use CStringLen in foreignexport?

2006-09-15 Thread Brian Hulley

Andreas Marth wrote:

Hi!

I try to export a Haskell function to VBA. (At the moment without
COM.) Because VBA seems to expect a String with length information I
tried to return a CStringLen as defined in Foreign.C.String.
But if I try to compile it I get an unacceptable argument type in
foreign declaration: CStringLen.
My reduced test program now is a strange Hallo world! program:


module Test where
import Foreign.C.String

foreign export stdcall hello :: IO CStringLen
hello :: IO CStringLen
hello = donewCStringLen (Hallo world!)


Do I do some thing wrong here? (If I use CString instead of
CStringLen and accordingly newCString instead of newCStringLen
everything compiles fine but VBA crashes.)


The FFI only supports a very limited range of types. CString is supported 
because it is just defined by:


   type CString = Ptr CChar

whereas CStringLen is defined as (Ptr CChar, Int) and tuples can't be passed 
through the FFI.


In any case, the BSTR type required by VBA is not so simple as a CStringLen. 

From the Microsoft Platfrom SDK docs,


   BSTRs are wide, double-byte (Unicode) strings on 32-bit Windows 
platforms

and narrow, single-byte strings on the Apple® PowerMacT.

   The length is stored as an integer at the memory location preceding the 
data in the string.


I assume that this means that on 32 bit Windows, the format of a BSTR is:

   Word16 -- low word of length
   Word16 -- high word of length
   Word16 -- first char of string
...

so you could try creating an array of Word16's in that format and passing 
them, perhaps something like:


   import Data.Word
   import Data.Bits
   import Foreign.Marshal.Array
   import Foreign.Ptr

   type BSTR = Ptr Word16

   createBSTR :: [Char] - IO BSTR
   createBSTR s = do
   let
   len :: Word32 = fromIntegral (length s)
   low :: Word16 = fromIntegral (len .. 0x)
   high :: Word16 = fromIntegral (shiftR len 16 .. 0x)
   newArray ([low, high] ++ map (fromIntegral . fromEnum) s)

   foreign export stdcall hello :: IO BSTR
   hello :: IO BSTR
   hello = createBSTR Hello world!

(The above code compiles but is untested)
Regards, Brian.
--
Logic empowers us and Love gives us purpose.
Yet still phantoms restless for eras long past,
congealed in the present in unthought forms,
strive mightily unseen to destroy us.

http://www.metamilk.com 


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


Re: [Haskell-cafe] Why am I not allowed to use CStringLen inforeignexport?

2006-09-15 Thread Brian Hulley

Brian Hulley wrote:

I assume that this means that on 32 bit Windows, the format of a BSTR
is:
Word16 -- low word of length
Word16 -- high word of length
Word16 -- first char of string
 ...


The above is not quite correct. It appears from 
http://www.oreilly.com/catalog/win32api/chapter/ch06.html that the length 
must preceed the actual BSTR, thus you must give VBA a pointer to the first 
*char* in the string not the actual start of the array of Word16's in 
memory. Furthermore, it appears that a terminating NULL is still needed even 
though the string itself can contain NULL characters. No only that, but the 
length must be given as the number of *bytes* (excluding the terminating 
NULL) not the number of characters.


Therefore here is a revised attempt at creating a Win32 BSTR:

   import Data.Word
   import Data.Bits
   import Foreign.Marshal.Array
   import Foreign.Ptr

   type BSTR = Ptr Word16

   createBSTR :: [Char] - IO BSTR
   createBSTR s = do
   let
   len :: Word32 = fromIntegral (length s * 2)
   low :: Word16 = fromIntegral (len .. 0x)
   high :: Word16 = fromIntegral (shiftR len 16 .. 0x)
   arr - newArray ([low, high] ++ map (fromIntegral . fromEnum) s ++ 
[0])

   return $! plusPtr arr 4

   foreign export stdcall hello :: IO BSTR
   hello :: IO BSTR
   hello = createBSTR Hello world!

Regards, Brian. 


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


Re: [Haskell-cafe] ambiguous partially defined type problem

2006-09-14 Thread Brian Hulley

Maarten wrote:

For a project involving I use some partially defined node (in this
case a simple record, in my project state transformers) in which the
defined part is common to all nodes, and the custom part is different
for each node. They have to become anonymous so I can put them in a
list of connections from each node to another.

For some reason GHC complains of 'ambigous type variable' in the code
below. The thing is, part of the code may be undefined, but since I'm
(explicitly) not using that part, why would GHC care? Are there other
solutions to this problem? Any pointers or comments appreciated.

-- data structure with custom and common part
data Node cust = Node cust Common
   deriving (Show,Typeable)

-- anonymous data structure to put use in list
data AN = forall ar. (Show ar, Typeable ar) = AN ar

instance Show AN where
   show (AN an) = AN ( ++ show an ++ )

-- common part
data Common = Common Integer
   deriving (Show,Typeable)

data Custom = Custom Integer
   deriving (Show,Typeable)

data Custom2 = Custom2 Integer
   deriving (Show,Typeable)

-- extract common part, ignoring type of custom part
getCommon :: forall gc. (Node gc) - Common
getCommon (Node cust com) = com

main = do
   let a = AN (Node (Custom 5) (Common 10))
   let b = case a of (AN a') - getCommon (case (cast a') of Just a''
- a'')
   putStrLn $ ok: ++ show b


Hi Maarten -
The problem is that AN is far too general. The compiler can't tell that 
you've wrapped a Node, so the call to getCommon will fail to typecheck.


Even if the compiler did know, by some other means, that a Node had been 
wrapped, Haskell doesn't support true existentials, so the type signature 
for getCommon doesn't do what I think you mean ie:


   getCommon :: forall gc. (Node gc) - Common

is the same as writing:

   getCommon :: Node gc - Common

whereas you'd really need an existential:

   getCommon :: (forall gc. Node gc) - Common

The fact that gc is not used in the definition of getCommon doesn't matter, 
since the type system has to just use the same rules for type inference 
regardless of the content of the function. In other words, without true 
existentials, or some other extension to the type system, there is no way to 
propagate the fact that the actual binding for a type variable is never 
required. Also, AFAIK there is no guarantee that Node Int Common and Node 
String Common would always be laid out in memory in the same way - the 
compiler is allowed to use special optimized layouts for particular 
instantiations of cust (even though it probably won't be clever enough to do 
this at the moment in Haskell implementations).


I suggest you wrap the custom part separately instead of wrapping the whole 
Node eg:


   data Custom = forall cust. ICusom cust = Custom cust

   data Node = Node Custom Common

where the ICustom class is whatever class you need to be able to do anything 
useful with cust.

Alternatively, you could wrap the custom part within the node as in:

   data Node = forall cust. ICustom cust = Node cust Custom

   getCommon :: Node - Common
   getCommon (Node cust com) = com

Regards, Brian.
--
Logic empowers us and Love gives us purpose.
Yet still phantoms restless for eras long past,
congealed in the present in unthought forms,
strive mightily unseen to destroy us.

http://www.metamilk.com 


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


Re: [Haskell-cafe] Re: Numeric type classes

2006-09-13 Thread Brian Hulley

Henning Thielemann wrote:

On Wed, 13 Sep 2006, Lennart Augustsson wrote:

I don't think Haskell really has the mechanisms for setting up an
algebraic class hierarchy the right way.  Consider some classes we
might want to build: SemiGroup
Monoid
AbelianMonoid
Group
AbelianGroup
SemiRing
Ring
...

The problem is that going from, say, AbelianMonoid to SemiRing you
want to add a new Monoid (the multiplicative) to the class.  So
SemiRing is a subclass of Monoid in two different way, both for +
and for *.
I don't know of any nice way to express this is Haskell.


Thanks for confirming what I wrote. :-)


If the above is equivalent to saying Monoid is a *superclass* of SemiRing 
in two different ways, then can someone explain why this approach would not 
work (posted earlier):


   data Multiply = Multiply
   data Add = Add

   class Group c e where
   group :: c - e - e - e
   identity :: c - e
   inverse :: c - e - e

   instance Group Multiply Rational where
   group Multiply x y = ...
   identity Multiply = 1
   inverse Multiply x = ...

   instance Group Add Rational where
   group Add x y = ...
   identity Add = 0
   inverse Add x = ...

   (+) :: Group Add a = a - a - a
   (+) = group Add

   (*) = group Multiply

   class (Group Multiply a, Group Add a) = Field a where ...

If the objection is just that you can't make something a subclass in two 
different ways, the above is surely a counterexample. Of course I made the 
above example more fixed than it should be ie:


   class (Group mult a, Group add a) = Field mult add a where ...

and only considered the relationship between groups and fields - obviously 
other classes would be needed before and in-between, but perhaps the problem 
is that even with extra parameters (to represent *all* the parameters in the 
corresponding tuples used in maths), there is no way to get a hierarchy?


Thanks, Brian.
--
Logic empowers us and Love gives us purpose.
Yet still phantoms restless for eras long past,
congealed in the present in unthought forms,
strive mightily unseen to destroy us.

http://www.metamilk.com 


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


Re: [Haskell-cafe] Weak pointers and referential transparency???

2006-09-12 Thread Brian Hulley

[EMAIL PROTECTED] wrote:

Brian Hulley wrote:
[...]

Ref.write proxiesRef $! (weakProxy : proxies)


(This is nothing to do with your main question, but the
strict application looks unnecessary there.  Its right hand
side is already a constructor cell.)


Yes, thanks for pointing this out.



[...]

In other words, if the entry for the proxy
in the table stored in the Model dies, can
I be absolutely 100% sure that this means
the proxy no longer exists in any shape or
form in the running program?


My reading of the semantics
(http://haskell.org/ghc/docs/latest/html/libraries/base/System-Mem-Weak.html#4)
is that you can be sure the proxy *object* is gone.


My problem is that I don't know what to make of the word object in the 
context of Haskell ie when can I be sure that a value is actually being 
represented as a pointer to a block of memory and not stored in registers or 
optimized out? Or is the compiler clever enough to preserve the concept of 
object despite such optimizations? I had been designing my Model/Proxy 
data types with the Java notion of everything is a pointer to an object 
but is this always correct relative to Haskell as a language or is it just a 
consequence of the current GHC implementation?




As for referential transparency...

Fan-in:
If you create equivalent proxies in different calls to
createProxy, it's possible that they'll end up referring to
the same object (e.g. if the compiler or RTS does something
fancy, or you use a memoised smart constructor).  So then a
single live proxy object *could* protect many elements of
your Weak Proxy list from scavenging.

Fan-out:
It would seem perverse to cry referential transparency!
and spontaneously clone one of your proxy objects.  That
*could* lead to deRefWeak returning Nothing while an
*equivalent* Proxy object is still alive.  Might you run
your program on an avant-garde distributed RTS?  ;-)


Someone else might even if I don't! ;-)

In the meantime I found a better solution to my original problem without 
needing to use weak pointers: I now make the proxy pull the changes from the 
model instead of making the model push them to all registered proxies, so 
there is no longer any need to have a table of registered proxies hence no 
need for weak pointers.


Thanks,
Brian.
--
Logic empowers us and Love gives us purpose.
Yet still phantoms restless for eras long past,
congealed in the present in unthought forms,
strive mightily unseen to destroy us.

http://www.metamilk.com 


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


Re: [Haskell-cafe] Re: Numeric type classes

2006-09-12 Thread Brian Hulley

Bryan Burgers wrote:

That being said, I'll have to play the other side of the coin: it
would probably be a little bit of a pain to have to define instances
of each data declaration (Integer, Int, Float, Matrix, Complex, etc.)
on each of these seperate classes--especially when being in a certain
class usually implies being in another (ie, the definition of a set
being a field requires that that set is a group, right?)


Aaron Denney wrote:

On 2006-09-12, Bryan Burgers [EMAIL PROTECTED] wrote:

And another problem I can see is that, for example, the Integers are
a group over addition, and also a group over multiplication;


Not over multiplication, no, because there is no inverse.

I know of no good way to express that a given data type obeys the
same interface two (or more) ways.  Some OO languages try to handle
the case of of an abstract base class being inherited twice through
two different intermediate classes, but none of them do it well.


How about:

   data Multiply = Multiply
   data Add = Add

   class Group c e where
   group :: c - e - e - e
   identity :: c - e
   inverse :: c - e - e

   instance Group Multiply Rational where
   group Multiply x y = ...
   identity Multiply = 1
   inverse Multiply x = ...

   instance Group Add Rational where
   group Add x y = ...
   identity Add = 0
   inverse Add x = ...

   (+) :: Group Add a = a - a - a
   (+) = group Add

   (*) = group Multiply

   class (Group Multiply a, Group Add a) = Field a where ...

Regards, Brian.
--
Logic empowers us and Love gives us purpose.
Yet still phantoms restless for eras long past,
congealed in the present in unthought forms,
strive mightily unseen to destroy us.

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


  1   2   3   4   >