Re: ghci balkiness on OS X?

2014-10-24 Thread Thomas Hallgren
I have noticed sluggish behaviour in ghci (ghc-7.8.3, OS X 10.9.5). In my case
at least, it seems to be caused by the idle time full garbage collection that
happens after 0.3s of idle time by default.

When you have say 300MB of live data in the heap, a major GC can take 0.5s or
so, and this is very noticeable when it happens as soon as there is more than a
0.3s pause between key strokes.

Foruntately, the idle time GC can be turned off by running ghci +RTS -I0, and
when I do that the problem goes away. Alternatively, using a longer timeout
(e.g. -I2) is enough to prevent the major GCs from happening while you are
typing, so it also helps a lot.

Thomas H

On 2014-10-24 07:37, Judah Jacobson wrote:
 I haven't seen this before myself (running on OS X), though in the past we 
 had a
 report of slowdown in long-running ghci sessions which was hard to reproduce. 
 What versions of GHC and OS X are you using?
 Do you know if this is a problem with text entry in general or only 
 If you run the command
 :m +System.IO Control.Exception Control.Monad
 (hSetBuffering stdin NoBuffering  hSetEcho stdin False  forever (getChar 
 \c - putStr ['{',c,'}'])) `finally` (hSetEcho stdin True  hSetBuffering 
 and hold down the 'a' key, does it smoothly output {a}{a}{a}... or does it
 have similar hiccups?
 On Tue, Oct 21, 2014 at 5:02 PM, Evan Laforge wrote:
 On my OS X, if I load a couple hundred modules into ghci as bytecode,
 text entry gets balky and laggy.  So e.g. if I hold down a key, the
 letters will stream in but have frequent hiccups.  This seems to
 adversely affect haskeline as well, such that, using vi mode,
 sometimes ^[ to move to command mode will be lost, or it will
 spontaneously go to insert mode, or ^[ followed by 'h' will be just
 beep and remain in insert mode.  If I load most of the modules
 compiled, this doesn't happen, or at least is not nearly so bad.
 It doesn't seem to be due to background work by ghci or anything,
 because it doesn't matter how long I wait after loading the modules.
 My previous random guess was that increased memory use made the GC
 work more, and my pauses were due to major collections.  But when I
 try on linux, ghci remains responsive no matter how many modules I
 load, so maybe it's an OS X only problem.
 Do any other OS X users see this effect?
 Glasgow-haskell-users mailing list
 Glasgow-haskell-users mailing list

Glasgow-haskell-users mailing list

Re: Problem with the object file name of the Main module.

2014-01-13 Thread Thomas Hallgren
The main module doesn't have to be called Main. You can specify a different name
with the -main-is option. That seems like the easiest way to avoid the object
file name clash.

By the way, this problem only seems to arise when the -odir flag is used. If my
Main module is in A.hs and I compile it with ghc --make A.hs, I get A.o,
A.hi and an executable file A. (Tested with GHC 7.6.3.)

Thomas H

On 2014-01-13 19:22, Christian Brolin wrote:
 No. As a workaround I remove the Main.o file after the executable has been
 linked. It works, but it has its drawbacks.
 On 2014-01-12 17:23, Carter Schonwald wrote:
 Christian, have you tried using cabal? People write cabal files with multiple
 executables being generated all the time.  

 On Sunday, January 12, 2014, Christian Brolin wrote:


 The documentation (version 7.6.3) section 7.7.2 Output files says that 
 source file name of the Main module does not have to be Main.hs making it
 possible to have several Main modules in separate source files in the
 same directory. While this is true and promising it is seems to be
 unusable since GHC always compiles the main source file into an object
 file called Main.o.

 Glasgow-haskell-users mailing list

 Glasgow-haskell-users mailing list

Glasgow-haskell-users mailing list

[Haskell-cafe] Hackage upload problem

2013-08-07 Thread Thomas Hallgren

I get the following error when I try to upload gf-3.5.tar.gz [1] to Hackage.

400 Error in upload
could not extract gf-3.5 directory from gf-3.5.tar.gz

I get the same error when I try to Check the previous version, gf-3.4.tar.gz
[2], which was uploaded without problems 6 months ago [3], so it seems that
something has changed on the server.

Does anyone know what it could be that is going wrong? Is there a way to get a
more informative error message?

Thomas H


Haskell-Cafe mailing list

Re: [Haskell-cafe] Hackage upload problem

2013-08-07 Thread Thomas Hallgren
On 2013-08-07 17:06 , Duncan Coutts wrote:
 On Wed, 2013-08-07 at 14:32 +0200, Thomas Hallgren wrote:

 I get the following error when I try to upload gf-3.5.tar.gz [1] to Hackage.

  400 Error in upload
 could not extract gf-3.5 directory from gf-3.5.tar.gz

 I get the same error when I try to Check the previous version, gf-3.4.tar.gz
 [2], which was uploaded without problems 6 months ago [3], so it seems that
 something has changed on the server.

 Does anyone know what it could be that is going wrong? Is there a way to get 
 more informative error message?
 You're welcome to try uploading it to the and
 see if that gives a more informative error message. If it's a poor error
 message there then we can fix that.
 Duncan didn't work either, it says:

Reached disk quota of 100 bytes.

gf-3.5.tar.gz is a lot bigger than 100 bytes. I am guessing this restriction
only applies on new-hackage, and that there is a different problem on old 

Thomas H

Haskell-Cafe mailing list

Re: [Haskell-cafe] Rewrite this imperative in FP way

2012-02-06 Thread Thomas Hallgren
How about this:

  import Array

  a = [1,1,1,1]
  b = [0,1,2,3]
  c = [0,2]

  d = elems $ accumArray (+) 0 (0,3) [(i+j,a!!i) | i-b, j-c, i+j3]

Thomas H

On 2012-02-06 12:01 , Haisheng Wu wrote:
 *d = [sum $ map (a !!) [i | i - b, j - c, i + j  3, i + j == dIndex] | 
 - [0..3]] *
 This is cool.
 On Sun, Feb 5, 2012 at 5:07 PM, L Corbijn wrote:
 On Sun, Feb 5, 2012 at 7:28 AM, Haisheng Wu wrote:
  a = [1,1,1,1]
  b = [0,1,2,3]
  d = [0,0,0,0]
  for i in b:
for j in c:
  if (i+j)3:
d[i+j] += a[i]
  My just work implementation in Haskell
  Another people implementation in Haskell with Monad and it turns out 
  and very imperatively.
  Do you have any cool solution in FP way?
  Haskell-Cafe mailing list
 There are several ways to make it nicer.
 Without assumption on what lists a, b and c contain it can be written as
 d = [sum $ map (a !!) [i | i - b, j - c, i + j  3, i + j == dIndex]
 | dIndex - [0..3]]
 With the assumption that b and c are both [0..3] this can be 'improved' to
 d = (take 3 . map sum . tail $ inits a) ++ replicate (4 - 3) 0
 This generates the first three values by the complicated expression
 and then adds the extra zero's by using the replicate expression. This
 works as the value of the i-th element of d is the sum over the first
 i elements in a if i  3 and 0 otherwise. A list of lists with the
 first i elements is generated with 'tail $ inits a' which is then
 summed and restricted to length 3.
 An alternative for this is
 d = (take 3 . snd $ mapAccumL (\acc ai - (acc + ai, acc + ai)) 0 a)
 ++ replicate (4 - 3) 0
 Where the summation and tail generating is done in the mapAccumL function.
 P.S. Yes the replicate (4-3) 0 can be replaced by [0], but I wanted to
 explicitly include the length (4) of the expected list.
 Haskell-Cafe mailing list

Haskell-Cafe mailing list

[Haskell-cafe] Re: Haskell not ready for Foo [was: Re: Hypothetical Haskell job in New York]

2009-01-08 Thread Thomas Hallgren

On 2009-01-08 12:10, Achim Schneider wrote:

Manlio  wrote:

Unfortunately Haskell is not yet ready for this task.

Could you -- or someone else -- please elaborate on this?

I think Haskell is ready for a lot more than most people think. How about an 
operating system in Haskell, for example? I think House shows that it could be done.

I've heard it once in the context of a webbrowser, the reason given was
that ghc doesn't deallocate memory, that is, the gc heap only
increases. I doubt it'd be hard to fix,

Even if the GHC RTS doesn't return unused heap memory to the operating system, I 
don't see why this would prevent you from implementing a useful web browser in 

As a comparison, my Firefox process currently uses 717MB of memory. I usually 
restart Firefox every day to bring the memory use down to a reasonable level. 
The situation would probably be the same if I used a browser implemented in Haskell.

Incidentally, I did implement a web browser in Haskell back in the 90s, and it 
worked fine :-) But that was before JavaScript and CSS, so it would take some 
work to make it useful on the web of today...

Thomas Hallgren
Haskell-Cafe mailing list

[Haskell] Re: Getting a function dependency graph from source

2006-10-12 Thread Thomas Hallgren
Durward McDonell wrote:
 Yes, this is exactly what I wanted!  Thanks, and thanks for writing
 it all in the first place. :-)
 However, I haven't quite been able to get it to work fully. ...  What am I 
 doing wrong?

If you use pfesetup to create the project, prelude and library modules will be
included as needed.

Haskell mailing list

[Haskell] Re: Getting a function dependency graph from source

2006-10-11 Thread Thomas Hallgren

The pfe command line tool from the Programatica Project has functionality that
seems to fit fairly well with what you are asking for:

pfe deps   -- lists function level dependencies
pfe needed -- lists everything needed by a definition
pfe dead   -- lists unused definitions
pfe slice  -- extract a slice by eliminating unused defintions

For more information, and downloads, see

Thomas H

Durward McDonell wrote:
 Hello.  This seems like a basic question, but I haven't
 been able to find an answer.  I have a pile of Haskell
 code that is compiled into a library, and a Haskell program
 that uses this library.  What I would like is something
 that will look at my program and follow the function calls
 until it gets to the Prelude.  I want to know which functions
 in the library and in the Prelude actually get used (at
 least potentially).


Haskell mailing list

[Haskell-cafe] Re: Editors for Haskell

2006-06-01 Thread Thomas Hallgren

Brian Hulley wrote:

Another thing which causes difficulty is the use of qualified operators, 
and the fact that the qualification syntax is in the context free 
grammar instead of being kept in the lexical syntax (where I think it 

You are in luck, because according to the Haskell 98 Report, qualified 
names are in the lexical syntax!

So, C.f is a qualified name, but C . f is composition of the Constructor 
C with the function f.

Thomas H

Haskell-Cafe mailing list

Re: Memory leak in Fudgets

2006-03-09 Thread Thomas Hallgren


I found and fixed this space leak in the Fudget library (it was a malloc without 

Thomas H

Simon Marlow wrote:

Dimitry Golubovsky wrote:

I wrote a very simple Fudgets program (just copies stdin to stdout, no
graphics involved)

I found out that the program grows in memory.

basically the extra memory is either mmap()'d or malloc()'d, probably by 
some code in your program or a library it uses

Glasgow-haskell-users mailing list

Re: [Haskell-cafe] Haskell GUI on top of Xlib?

2005-11-27 Thread Thomas Hallgren


Dimitry Golubovsky wrote:

Do there exist Haskell graphics/UI toolkits implemented on top of the 
X11 library (Xlib) without any intermediate C/C++ libraries (i. e. not 
WxHaskell for example)?

Fudgets is a GUI toolkit implemented in Haskell directly on top of Xlib:

Recent snapshots can be found at:

Thomas Hallgren

Haskell-Cafe mailing list

Re: [Haskell-cafe] programatica and haddock

2005-07-01 Thread Thomas Hallgren


Christian Maeder wrote:

I would like to see the advantages of both, programatica's documentation
generation and haddock, to be united. (programatica sources don't go
through haddock and have few type signatures that haddock could exploit,
and haddock comments are useless for programatica.)

Unfortunately, the markup used by both programs is different. {-+ in
programatica and {- | in haddock.

Is there any chance that both documentation approaches could be streamlined?

Yes, adding support for Haddock style comment markup to the current HTML 
renderer in the Programatica tools shouldn't be hard, so I might do 
that. If I also add support for generating Haddock style documentation, 
I could take advantage of the fact that the Programatica tools can infer 
types, to compensate for the lack of explicit type signatures in source 

Thomas H

Haskell-Cafe mailing list

Re: [Haskell-cafe] type inference and named fields

2005-06-26 Thread Thomas Hallgren

Bulat Ziganshin wrote:

i like O'Haskell because it's very close to traditional OO languages
in its ways to extend the types. why O'Haskell is not really
implemented as extension to GHC/Hugs? because it is not compatible
with System F?

O'Haskell *is* implemented as an extension of Hugs. Google for ohugs.

I don't think you need to abandon System F to support subtyping in a 
compiler. You just need to make the subtyping coercions explicit, 
similar to how overloading is supported by the dictionary translation.

Thomas H

Haskell-Cafe mailing list

Re: [Haskell-cafe] A Tool To Show Functions Relationship?

2005-06-09 Thread Thomas Hallgren

Dimitry Golubovsky wrote:

Does there exist a tool which given a Haskell source, shows functions
that are mutually recursive (i. e. call each other, even via calling
third, etc. functions)?

With pfe, the Programmatica tools command line interface, you can 
currently get a list of definition level dependencies like this 
(assuming your module is called Example):

% pfesetup +h Example.hs
% pfe deps Example

module DepExample:
   Hugs.Prelude.Monad Hugs.Prelude.= pointer idd
   Text.ParserCombinators.Parsec.Prim.many cpi
   Hugs.Prelude.return Declarator
   Hugs.Prelude.Monad Hugs.Prelude.= anyIdString
   Hugs.Prelude.return Hugs.Prelude.Either
   Hugs.Prelude.Left Hugs.Prelude. tkOp declarator

The dependency information is computed after type checking, so it 
includes dependencies on instance declarations (which are assign names 
starting with inst__).

I guess it would be usesful to also have an option to eliminate 
dependencies on imported stuff, and an option to display mutually 
recursive groups (strongly connected components of definitions).

Knowledge of that would help to split the
module into smaller modules without risk to create recursive modules.

The Programatica tools actually support mutually recursive modules, so 
that wouldn't be a problem. We are still waiting for other Haskell 
implementations to catch up :-)

Thomas H

Haskell-Cafe mailing list

Re: [Haskell-cafe] Bit fiddling

2005-05-17 Thread Thomas Hallgren
Florian Weimer wrote:
I'm toying a bit with Haskell and wondering what's the best way to
implement bit fiddling.  Most of my applications involve serializing
and deserializing small blobs (IP packets, for instance), and after
browsing the GHC library documentation, I'm not sure which appraoch I
should use.  That's why I'd appreciate pointers to sample code.

In the protocol stack in House [1], I have used parsing/unparsing 
combinators to (de)serialize network packets. This allows the code to be 
simple, pure and modular, even though you are dealing with data down to 
the bit level.

The way things work at the moment, the network device driver returns 
incoming packets as unboxed arrays of bytes (values of type UArray Int 
Word8), and the parsing combinators maintain these along with position 
information down to the bit level, allowing you to parse input bit by 
bit. The process is reversed in the unparsing combinators. (What would 
be nice to have for this is efficient library functions for manipulation 
of bit vectors of arbitrary dynamic size...)

The source code is available on the web, see for example modules 
Net.Ethernet, Net.ARP, Net.ICMP, Net.IPv4:
Note though that this is work in progress, there is not much 
documentation, and the code for several of the protocols is incomplete.

Thomas H
Haskell-Cafe mailing list

Re: [Haskell] The FunctorM library

2005-03-25 Thread Thomas Hallgren
Simon Peyton-Jones wrote:
|  class Functor f where fmap :: ...
|  class Functor m = Monad m where
| ...the usual stuff...
| fmap = liftM
It seems overkill to have a whole new language feature to deal with one
library issue. 

Perhaps it is...
For example, what if Functor T *is* defined explicitly, but in a later module?

I guess it would be the same as what happens now if you accidentally 
declare the same instance in different modules, i.e., the system would 
complain about overlapping instances.

Thomas H
Haskell mailing list

Re: ghc-6.4.20050220: panic! eval_data2tag...

2005-02-22 Thread Thomas Hallgren
I managed to distill my program into to the following small example that 
still exhibits the problem:

   module Bug where
   data S e = A | B | C | D | E | F | G | H | I deriving (Eq)
   newtype R = T (S R) deriving (Eq)
The output from 'ghc -c -O Bug.hs' is:
ghc-6.4.20050220: panic! (the `impossible' happened, GHC version 
   GHCziPrim.dataToTagzh{(w) v 95f}
 @ (Bug.S{tc r14v} recntBug.R{tc r14r})
 (__coerce (Bug.S{tc r14v} recntBug.R{tc r14r}) a{v s1Cm})

Please report it as a compiler bug to,
Thomas Hallgren
Glasgow-haskell-bugs mailing list

Re: self-import

2005-01-18 Thread Thomas Hallgren
Simon Peyton-Jones wrote:
I quite liked this idea until I thought of this:
module Doc.Pretty.Long( M.f, f ) where
  import qualified M( f )
  import Doc.Pretty.Long as M
  f x = x
The second import decl imports all the things exported by
Doc.Pretty.Long. But what does it export?  Well, M.f.  But what is M.f.
Well, it could be the f coming from 'import M.f'.  But wait!
Doc.Pretty.Long exports the locally-defined f too... and the second
import decl will make that be called M.f too.

Our module system paper has answers to this type of questions, since it 
deals with the meaning of recursive modules:
It is implemented in the Programatica Haskell front-end, which thus 
supports modules importing themselves in particular, and mutually 
recursive modules in general, without the need for boot .hi files. I 
wonder when other Haskell implementations are going to catch up? :-)

Thomas H
Glasgow-haskell-users mailing list

Re: [Haskell-cafe] coercion to Int

2004-12-31 Thread Thomas Hallgren
james pentland wrote:
what coercion can i use to get the below program to compile? ... various combinations of fromInteger, toInteger do not help.

Did you try fromIntegral?
   fromIntegral :: (Integral a, Num b) = a - b
fnK_ :: Int - Int
fnK_ x = round (sqrt x) -- line 2

Thomas H
Haskell-Cafe mailing list

Re: [Haskell-cafe] Equality of functions

2004-11-30 Thread Thomas Hallgren
Adam Zachary Wyner wrote:
Hi All,
After some weeks of experimenting and digging around, I understand that
functions cannot be compared for equality.  Thanks to Bjorn Lisper for
pointing this out.  I basically understand (?) the underlying mathematical
issue, which is that functions in general may have infinite domains...
Other suggestions?

You can define equality for functions with finite domains. See the 
enclosed Haskell module.

Loading package base ... linking ... done.
Compiling Finite   ( Finite.hs, interpreted )
Ok, modules loaded: Finite.
*Finite not == not
*Finite () == ()
*Finite () == (||)
Thomas H
module Finite where

instance (Finite a, Eq b) = Eq (a-b) where
  f == g = and [ f x == g x | x - allValues ]

-- A class for finite types

class Finite a where
  allValues :: [a]

instance Finite () where allValues = [()]

instance Finite Bool where allValues = [False,True]

--instance Finite Ordering where ...
--instance Finite Char where ...
--instance Finite Int where ...

instance (Finite a,Finite b) = Finite (a,b) where
  allValues = [ (x,y) | x-allValues, y-allValues]

instance Finite a = Finite (Maybe a) where
  allValues = Nothing:[Just x|x-allValues]

instance (Finite a,Finite b) = Finite (Either a b) where
   allValues = [Left x|x-allValues]++[Right y|y-allValues]

-- ...
Haskell-Cafe mailing list

Re: [Haskell-cafe] readEitherChan

2004-06-18 Thread Thomas Hallgren
Tomasz Zielonka wrote:
On Tue, Jun 15, 2004 at 06:29:59PM -0400, S. Alexander Jacobson wrote:

 readEitherChan::Chan a - Chan b - Either a b
 eitherChan a b left right = readEitherChan a b = either left right

... I think it would be safer to create once new Chan (Either a b), and then read from 
   createEitherChan :: Chan a - Chan b - IO (Chan (Either a b))

Although createEitherChan might be the best solution for some 
application, it would be interesting to know what the recommended way to 
implement the function eitherChan above is, if that is what you really need?

The eitherChan function corresponds to guarded nondeterministic choice, 
usually written (a?P)+(b?Q) process calculi, i.e., a rather fundamental 
concurrency operator.

Section 5 of [1] enumerates some reasons why guarded nondeterministic 
choice is not available as a primitive in Concurrent Haskell. Section 
5.2 describes a function select for nondeterministic choice, but I don't 
see how to use that to implement readEitherChan (or takeEitherMVar)...

I got interested in this the other day when I was contemplating reviving 
Gadget Gofer [2], by porting it to Concurrent Haskell. Gadget Gofer has 
a non-deterministic choice operator, though, so the port would probably 
require more work than I expected...

Thomas H
[1] Concurrent Haskell
[2] Lazy Functional Components for Graphical User Interfaces,
   Rob Noble, PhD thesis, York, 1996

Description: OpenPGP digital signature
Haskell-Cafe mailing list

Re: [Haskell] GHC binary for Cygwin

2004-03-19 Thread Thomas Hallgren
Thomas Hafner wrote:

Are somewhere GHC binaries for Cygwin available? I tried to cross
compile from Linux, but didn't succeed.
Maybe one want to answer me: ``Why is a cygwin port needed? There's
already a great MS W port!'', but: ...
In a ``pure'' Cygwin port all system calls should go through the
Cygwin libraries, of course.

I would be interested in GHC for Cygwin too!

The other day, I tried to compile the Fudgets library with GHC-MinGW. It 
didn't work, of course, and having GHC for Cygwin would presumably 
significantly reduce the amount of pain required to port it. (Support 
for certain Posix system calls and symbolic links would be helpful.)

At first I assumed that it would be fairly easy to create GHC-Cygwin 
from GHC-MinGW, but then I read the explicit statement in the 
documentation, that Cygwin is not supported, and was rather discouraged...

Fudgets already works many Unix-like systems, e.g. Linux and Mac OS X. 
There was also a port of HBC and Fudgets to Cygwin under Windows 95 many 
years ago.

Thomas H
Haskell mailing list

[Haskell-cafe] Re: Simple Fudgets-question

2004-01-26 Thread Thomas Hallgren
Henrik Berg wrote:

Thomas Hallgren [EMAIL PROTECTED] writes:


... All I want to do is to resend the input out on the output.

If that is all you want, this combinator is the right choice:

	throughF :: F a b - F a (Either b a)

Yes, but (Either b a) won't give me the input _together_ with the
output, will it?  I need a fudget that accepts some input, does some
work on it, and outputs the result _and_ the original input for
further processing by other fudgets.  As far as I can see, this means
I need a tupple (a, b), and not the disjoint sum (Either a b).

Aha, I suspected you wanted something more :-)

Fudgets are asynchronous in nature, so there is no single right way to 
merge two streams into a stream of pairs, and I guess that is why there 
is no combinator for it in the library. Here is some code I found in an 
old example, illustrating one way to do it...

collectF :: F (Either a b) (a,b)
collectF = absF (collectSP Nothing Nothing)
collectSP :: Maybe a - Maybe b - SP (Either a b) (a,b)
collectSP x y =
 case (x,y) of
(Just x,Just y) - putSP (x,y) (collectSP Nothing Nothing)
_ - getSP (\msg -
case msg of
   Right y - collectSP x (Just y)
   Left x - collectSP (Just x) y
-- This is how collectF was used:
--fileF = collectF==throughF fileDialogF==fileMenuF
Thomas H
Haskell-Cafe mailing list

Re: Any versions of Fudgets working with GHC-6?

2004-01-21 Thread Thomas Hallgren
Henrik Berg wrote:

... I was able to compile Fudgets when I removed 6.0.1, using
only 5.04.3.
Still don't understand why I coudn't get it compile with 6.0.1,

fudgets-030806.src.tar.gz compiles with GHC 6.0.1.

Fudgets does not yet compile with GHC 6.2, however, since _casm_ (which 
very conveniently allowed you to include C code fragments in your 
Haskell code) is no longer supported. For example, the Fudget library 
uses the following C preprocessor macro

#define SETI(ctype,p,i,field,v) (_casm_ ``((ctype *)%0)[%1].field=%2;'' ((p)::HT(ctype)) (i) (v) :: IO ())

to store values in arrays of records of various types. Is there a 
convenient way to do things like this without _casm_?

Thomas H
Haskell mailing list

ANN: Haskell tools from the Programatica project

2003-11-04 Thread Thomas Hallgren

For those who are curious about what we have been up to in the 
Programatica project (perhaps because you who saw the demo at the 
Haskell Workshop this year, or read the demo abstract), we now have a 
web page where you can

   * find out more about what the tools can be used for,
   * download binary snapshot of our command-line tools and graphical
 Haskell browser,
   * find out how to access the Programatica Tools CVS repository,
   * browse the source code on-line.
The location of the web page is:

Note that this is work in progress, we welcome feedback.

Also, while the tools we provide might contain some functionality useful 
to Haskell programmers, it should also be possible to reuse our source 
code (which has a lot in common with a Haskell compiler front-end) to 
build other Haskell tools. In fact, it has already been reused in the 
Haskell refactoring project at the University of Kent.

Thomas Hallgren
The Programatica Project
Haskell mailing list

Re: interact behaves oddly if used interactively

2003-10-02 Thread Thomas Hallgren
John Meacham wrote:

personally, I think the easiest solution would be to punt the whole
issue by having:
lazily read the file if it is mmapable or a pipe

eagerly slurp the whole file if it refers to a tty

I think this kind of irregular behaviour would make the IO functions 
even more difficult to understand. Why should some invokations of the 
same program exhibit utterly different space/time behaviour from others?!

mycomputer% ./myprogram
mycomputer% cat | ./myprogram
mycomputer% ./myprogram myfile
mycomputer% luit ./myprogram
of course this makes 'interact' not really interactive,

Exactly, it defeats the whole purpose of the interact function (to 
provide support for Landin-stream IO), so you might just as well remove 
it completely...

Thomas H

Haskell-Cafe mailing list

Re: lexer puzzle

2003-09-24 Thread Thomas Hallgren
Marcin 'Qrczak' Kowalczyk wrote:

A... should be split into A.. and .

I found a compromise: let's make it a lexing error! :-)

At least that agrees with what some Haskell compilers implement. No 
current Haskell compiler/interpreter agrees with what the report seems 
to say, that is that A... should be lexed as the two tokens A.. and 
., and similarly, A.where should be lexed as A.wher followed by e.

It seems that the source of the problem is the use of the (nonstandard) 
difference operator r1r2 in the specification of the lexical syntax in 
the Haskell report [1]. It was presumably fairly innocent and easy to 
understand originally, but I guess that nobody understood its 
consequences when qualified names were introduced.

Anyway, this should teach us not to use homemade pseudo formal notation 
when defining a new language, but to stick to well-established, 
well-understood, tool-supported formalisms...

For the Programatica Haskell front-end, I have now switched to a regular 
expression compiler that has direct support for the difference operator, 
so hopefully, our implementation agrees with what the report specifies. 
(This is not necessarily a good thing, though, since it makes our 
front-end different from all other Haskell implementations :-)

For what it is worth, I tested A..., A.where and A.-- in the main 
Haskell implementations and in the Programatica Haskell front-end. The 
input was two modules A and B:

1 module A where
3 wher = id
4 e = id
1 module B where
2 import A
4 x = (A.where)
5 y = x
Here is the result:

GHC: B.hs:4: parse error on input `where'
HBC: B.hs, line 4, Bad qualified name on input:eof
Hugs: ERROR B.hs:4 - Undefined qualified variable A.where
NHC98: Identifier A.where used at 4:6 is not defined.
PFE: ok
If line 4 in module B is replaced with x = (A...):

GHC: B.hs:4: Variable not in scope: `A...'
HBC: B.hs, line 4, Bad qualified name on input:eof
Hugs: ERROR B.hs:4 - Undefined qualified variable A...
NHC98: Identifier A... used at 4:6 is not defined.
PFE: B.hs:4,13, before ): syntax error
(A.. is lexed as A.. .)
If line 4 in module B is replaced with x = (A.--)

GHC: B.hs:4: Variable not in scope: `A.--'
HBC: B.hs, line 5, syntax error on input:=
(treats -- as the start of a comment)
Hugs: ERROR B.hs:4 - Undefined qualified variable A.--
NHC98: Identifier A.-- used at 4:6 is not defined.
PFE: B.hs:5,1, before : syntax error
(A.-- is lexed as A.- -)
I used the following versions

GHC 6.0.1
HBC 0..5b
Hugs 98 November 2002
NHC98 1.16
PFE 030912
Thomas H

Haskell mailing list

Re: Fudgets

2003-06-10 Thread Thomas Hallgren
Ashley Yakeley wrote:

Would it be worth rewriting Fudgets to take advantage of such recent 
advances in Haskell as monadic IO?
A rejuvenation of Fudgets, taking advantage of things like subtyping, 
multi-parameter classes with functional dependencies, syntactic sugar 
for arrows, making room for monadic IO, and using a more modern graphics 
subsystem, would probably make Fudgets much more interesting. Actually, 
Fruit [1], although it is independent work, could be seen as a 
redesign/rejuvenation of Fudgets.

Allowing arbitrary monadic IO inside fudgets is not impossible, see [2], 
but while it would give access to modern things like the FFI, it would 
also mean giving up some of the purity and elegance of fudgets. The old 
approach to IO, where every IO operation is a constructor in a data 
type, means that all IO operations can be examined and manipulated 
within the program in interesting ways, by just adding a wrapper around 
the main function. For example, when a fudget program is run with the 
-debug flag, a trace of all IO operations and their results is printed 
on stderr. As another example, the cacheF fudget wrapper speeds up 
fudget programs by caching the result of requests for colors, fonts and 
other GUI resources. It would be easy to write a wrapper that swaps the 
left and right mouse buttons, or makes a program ask for the user's 
permission before deleting a file. Try doing things like that by adding 
a wrapper around a value of type IO()!

I must confess I'm not all that familiar with Fudgets, although it 
certainly looks interesting. For what sort of problems is it currently 
the best solution?

I guess it depends on what you are comparing to, but if you like 
programming GUIs in a declarative style, you don't need the FFI but can 
live with the IO operations already provided by the fudget library 
(which includes file/directory access and networking), or perhaps you 
want to experiment with implementing your own special purpose widgets in 
Haskell (Fudgets implements its own widget set in Haskell), then using 
Fudgets might be a good choice. But when the GUI starts getting big and 
irregular, the plumbing can become a bit clumpsy (some would even say 
painful, worse than having a tooth pulled :-).

Thomas H
Haskell-Cafe mailing list

Re: Fudgets with GHC 5.04.3

2003-05-30 Thread Thomas Hallgren
Bas van Dijk wrote:

In hsrc/ghmklib and Contrib/Makefile, there are options for which make
tool to use. I think the 030414 version uses humake by default.
env GHCFUDGETS=../GhcFudgets ../bin/ghuxmake -batch -cpp -O2 ContribFudgets.hs
../bin/ghuxmake: line 44: ghumake: command not found
The Contrib/Makefile also uses humake by default, but can change it to 
use hmake (ghc --make doesn't work here...).

What do I have to change in: Contrib/Makefile to get it going?

Install hmake, and comment in the definition

   GHCXMAKE = ../bin/ghcxmake -cpp

and comment out the other definition of GHCXMAKE. (Or install humake.)

If the source distribution doens't work then I gues I just have to use the 
binaries... :-(

Yes, why not? The point of binary distributions is to make things easier 
for users... :-)

Thomas H

Haskell mailing list

Re: Fudgets with GHC 5.04.3

2003-05-29 Thread Thomas Hallgren
Bas van Dijk wrote:

Great! it's working now...

I accidently downloaded the newest untested version (April 2003) from the 
Fudget website. That version gave errors while making.

In hsrc/ghmklib and Contrib/Makefile, there are options for which make
tool to use. I think the 030414 version uses humake by default.
I know it's something like: 

ghc -package Fudgets myfirstfudgetsapp.hs

The fudget library was created long before GHC's package system and has
not (yet) adapted to use it, so instead we provide two wrapper scripts
that pass the right flags to GHC. So, do
   ghcxmake myfirstfudgetsapp

(requres hmake) or

   ghuxmake myfirstfudgetsapp

(requires humake). You can include additional flags to pass to GHC.

Also, some recent binary snapshots (I added a new one for GHC 5.04.3
today) are availalbe from

We have fixed some small bugs and performance problems since the h13w
Thomas H
PS Although the package system is useful, I think the solution with a
global configuration file is an inherently bad idea...
Haskell mailing list

Uninformative error message from getModificationTime

2003-03-28 Thread Thomas Hallgren

If I run the program

   main = print = readFile god

and god doesn't exist, I get the following informative error message

   Fail: does not exist
   Action: openFile
   Reason: No such file or directory
   File: god
However, if I run the program

   import Directory
   main = print = getModificationTime god
I get the message

   Fail: does not exist
   Action: withFileStatus
   Reason: No such file or directory
where the file name isn't included. I guess I could write my own wrapper 
around getModificationTime to generate a better error message, but 
presumably other functions implemented by calls to withFileStatus suffer 
from the same problem, so it is better to fix the problem there.

This was tested with GHC 5.04.2 under Linux.

Thomas H
I think it would be a great idea.
(Ghandi's answer when asked what he thought of Western Civilization)
Glasgow-haskell-bugs mailing list

Re: -O doesn't work with gcc-3.2?

2002-11-23 Thread Thomas Hallgren

Anatoli Tubman (by way of Anatoli Tubma) wrote:

ghc fails with this message:

Prologue junk?: .globl __stginit_Main
   pushl   %ebp
   movl%esp, %ebp

It works without -O. I'm on stock Mandrake 9.0 system.

It appears that the version of GCC 3.2 supplied with Mandrake 9.0 
ignores the -fomit-frame-pointer flag, and this confuses GHC's mangler. 
The version of GCC supplied with RedHat 8.0 (gcc version 3.2 20020903) 
does not seem to have this problem...

Thomas H

Glasgow-haskell-users mailing list

Negative literals and the meaning of case -2 of -2 - True

2002-05-16 Thread Thomas Hallgren


The Haskell report seems pretty clear about the meaning of numeric 
literals and negation in expressions: -2 should be interpreted as negate 
(fromInteger 2). That is, negated literals are not treated specially, 
the general rule -(e) == negate (e) applies. (See section 3.2 and 3.4 
of the Haskell 98 report [1].)

The mening of numeric literals in patterns also seems clear (section 
3.17.2 says  The interpretation of numeric literals is exactly as 
described in Section 3.2), but the report does not say anything explicit 
about negated literals, although negated numeric literals is a special 
case in the syntax. Presumably, numeric literals should be understood as 
including negated numeric literals in the sections defining the meaning 
of pattern matching?

To find out how Haskell implementations treat negated literals, I tested 
the following program:

main = print (minusTwo,trueOrFalse)

minusTwo = -2::N

trueOrFalse =
case minusTwo of
  -2 - True
  _ - False

data N = Negate N | FromInteger Integer deriving (Eq,Show)

instance Num N where
  negate = Negate
  fromInteger = FromInteger

The result is:

* hugs Dec 2001: main outputs: (FromInteger (-2),True)
* ghc 5.02.2: main outputs: (FromInteger (-2),True)
* hbc 0..5b: main outputs: (Negate (FromInteger 2),False)
* nhc98 1.12: compiler outputs: Fail: What? matchAltIf at 7:13

 From this I conclude that hbc is the only Haskell implementation that 
treats negated literals in expressions in accordance with the report, 
but it treats negated literals in patterns differently. Hugs and ghc 
treat expressions and patterns consistently, but they disagree with the 
report. Nhc98 appears to be buggy.

Perhaps this is not a serious problem, but wouldn't it be nice if the 
report and the implementations agreed on this point? I bet Simon PJ will 
suggest that the report is changed to match GHC, rather than vice versa, 
as usual :-) I think the report is right, but the meaning of negated 
literals in patterns could be clearer...


[1] Haskell 98 report

Haskell mailing list

stripcomments 1.0

2002-03-21 Thread Thomas Hallgren


There now is a program that strips comments and blank lines properly. 
You can get the Haskell source code from:

How hard it is to do a real job of course depends on what you start 
from. I happened to have a lexer for Haskell, that was really easy to 
reuse for this purpose!

Thomas Hallgren

Nicholas Nethercote wrote:

On Mon, 18 Mar 2002, Kevin Glynn wrote:

  Are there any programs to strip comments and blank lines from a Haskell
  source file, that work on normal and literate programs?

Doing a real job is 'hard' 

I'm surprised there aren't programs out there that do this properly.

Haskell mailing list

Re: unification

2002-01-28 Thread Thomas Hallgren

David Feuer wrote:

 Has anyone written an efficient purely-functional
 implementation of unification (for type checking)?
Well, if you have ever used hbc or nhc, you have used type checkers
containing purely functional implementations of unification. Purely
functional unification can be efficient enough for practical purposes...

Thomas H

Haskell-Cafe mailing list

/tmp/ghc13435.lpp:388: Non-exhaustive patterns in function zip_ty_env

2001-10-16 Thread Thomas Hallgren


When I compile the following module,

module ZipTyEnvBug where

type A i = i
type B = A

I get

ghc-5.02: panic! (the `impossible' happened, GHC version 5.02):
/tmp/ghc13435.lpp:388: Non-exhaustive patterns in function 

Changing the second declaration to

type B i = A i

helps, but the Haskell 98 report (section 4.2.2) explicitly allows the 
lhs of a type sysonym declaration to be of higher kind...


Thomas Hallgren

Glasgow-haskell-bugs mailing list

Re: Strange error in show for datatype

2001-10-04 Thread Thomas Hallgren

Olaf Chitil wrote:

Anyway, I find all these suggestions about occurrence and variance of
type variables rather complicated. 

As I suspected, some people are afraid of subtypes :-) But variances are 
not that difficult to compute. For example, it is part of the O'Haskell 
type system, which is implemented in ohugs [1,2].

Koen Claessen wrote:

  Hugs show ([] :: [Char])

  Hugs show ([] :: [Int])

Oops. I was wrong when I wrote that the proposed way of dealing with 
ambiguity gives the same result as if you manually disambiguate whith an 
arbitrary type. Sorry.

As an example of why passing undefined dictionaries fails, consider how 
'show ([]::[T])' for some type T is computed: it would first call the 
show method of the Show instance for lists, which in turn calls the 
showList method for the type T. Hence, if we pass an undefined 
dictionary for Show a to compute the result of 'show [] :: Show a = 
String', we would try to extract showList from the undefined dictionary, 
leading to an undefined result, rather than a string like []...

But I think the method of simplifying types based on ideas from 
subtyping and using instances for the Empty type (which actually 
contains _|_ , like all other types), could still be useful. It should 
not be seen as a semantics preserving transformation, but as a new kind 
of defaulting mechanism, where default instances are specified by giving 
instance declarations for the Empty type.

For the primary example with the Show class, with this approach, adding

instance Show Empty

would be enough to get

Hugs show []

thanks to the default for the showList method in the Show class. Things like

Hugs show (Left True,Nothing)
(Left True,Nothing)

would also work although the above instance declaration in effect leaves 
the show method for Empty undefined.
 (Another way to achieve this would perhaps be to just extend the 
current default declarations to allow defaults to be declared for 
arbitrary classes, not just the Num class...)

Simon-Peyton Jones wrote:

... And you're telling us that the subtyping folk worked this
out yonks ago.  Excellent!  (Reference, for this particular point?)

As I guess has become aparent, I don't have a reference to a complete 
solution to this problem, but using ideas from subtyping to solve this 
has been in the back of my head for many years, although it seems I have 
been too naive, not taking laziness and coherence into account. My 
underlying intuition comes from working with ideas from papers like [3] 
and [4].

My implemention mood has
suddenly past.

Does this mail do anything for your implementation mood?

Thomas Hallgren

PS By the way, perhaps theorems for free (e.g., [5]) also have something 
to contribute to the solution of this problem?


Haskell mailing list

Re: Strange error in show for datatype

2001-10-03 Thread Thomas Hallgren

  Simon Peyton-Jones wrote:

   msg :: forall a.  Show a = String

Urk!  What Show dictionary should Hugs use when evaluating msg?

You may say it doesn't matter, but in general that's not the case.  
In the case of class Num, for example, we might have

   expr = 3+4
   msg = show expr

and then the type involved really does matter.

I wonder if the following is true.  Given the ambiguous type

   forall a.  Show a = T  (where a does not appear in T)

it's OK to pass the bottom dictionary. ...

Type systems with subtyping have what is needed to determine when the 
choice of dictinionary doesn't matter.

In type systems with subtyping, the most general type is the minimal 
type. This means that type variables that occur only positively (in 
covariant positions) can be minimized (and that negative variables can 
be maximized). If there is an empty type, Empty say, which is a subtype 
of all other types, then the type

forall a . Show a = T

is just as general as the type

Show Empty = T

since a occurs only positively in Show a = T, taking into account the 
occurences of a in the definition of the Show class. The requirement 
that a does not appear in T is overly restrictive. This simplification 
can be made as long as all occurences of a in T are positive.

Assuming a language with subtyping that simplifes types in this way, 
expressions like

show undefined
show []
show Nothing
show (Left False)

would no longer be ambiguously overloaded. If the prelude provides

instance Show Empty -- no methods need to be defined

then types of the above expressions would all reduce to String, and they 
would all compute to the expected results (i.e., the result you would 
get by manually disambiguating the types, e.g., show ([]::[Int])).

The same trick applies to the Eq class, so that, e.g., [] == [] would be 
unambiguous and compute to True.

So, obviously, the next version of Haskell should have a type system 
with subtyping, don't you agree? :-) 

Thomas Hallgren

PS In some previous version of Haskell (1.3?), the Prelude defined an 
empty type called Void, but it has since been removed. Apparently, 
people didn't see the potential of Void...

PPS For those who are afraid of subtypes :-), I think you can use the 
information about variance of type variables used in subtype inference, 
to determine when the choice of dictinonary doesn't matter, without 
introducing subtyping in the languange...

Haskell mailing list

Re: ghc-pkg

2001-10-02 Thread Thomas Hallgren

Simon Marlow wrote:

Perhaps it would be easier to have hmake just invoke 'ghc --make' under
the hood?

I don't think ghc --make is mature enough to replace other make tools 
yet. For example, when trying to compile Fudgets with ghc-5.02 --make 
-O2, with GHCRTS=-M100M, I got

GHC's heap exhausted;
while trying to allocate 0 bytes in a 9744-byte heap;
use the `-Hsize' option to increase the total heap size.

after about 2/3 of the library had compiled. GHC also left 54MB of junk 
behind in /tmp. I don't know exactly how big the heep needs to be, or 
how much free space in /tmp is needed to compile all of fudgets (285 
modules), but I think it is clear that this behaviour is horrendous...

As a comparison, using hmake, or some other make tool, fudgets compile 
just fine with ghc-5.02 -O2 , GHCRTS=-M40M (perhaps even less, I haven't 
tried), using only a few megabytes of space in /tmp.

Additionally, ghc --make lacks (AFAIK) several useful features found in 
other make tools (although not all in the same tool...):

   1. The ability to distingush directories containing source code to be
  compiled from directories containing previously compiled code
  (hmake has the flags -P and -i, hbcmake has -i and -I). (I guess
  you could use -package-conf as a cumbersome substitute, though.)
   2. The ability to specify compiler flags for individual modules
  without putting them in the source code. (Some flags are 'static'
  and can not be put in the source code.)
   3. The ability to compile several modules in parallel, on a
  multi-processor machine, or a network of workstations.
   4. The ability to automatically invoke program generators (e.g. happy)...
   5. A graphical user interface.

Thomas Hallgren

Glasgow-haskell-users mailing list

GHC 5.02, import Prelude hiding ...

2001-09-27 Thread Thomas Hallgren


The following program was accepted by previous versions of GHC, but is 
not in GHC 5.02

module HidingBug where
import Prelude hiding (lookup)

lookup env x = Prelude.lookup x env

Instead, you get the error message

HidingBug.hs:4: Variable not in scope: `Prelude.lookup'

This behaviour does not seem to agree with (the latest version of) the 
Haskell 98 Report, which in section 5.6.1 says

The Prelude module is imported automatically into all modules as if
by the statement `import Prelude', if and only if it is not imported
with an explicit import declaration. This provision for explicit
import allows values defined in the Prelude to be hidden from the
unqualified name space. The Prelude module is always available as a
qualified import: an implicit `import qualified Prelude ' is part of
every module and names prefixed by `Prelude.' can always be used to
refer to entities in the Prelude.

and in section 5.3 says

The effect of multiple import declarations is strictly cumulative...

Thomas Hallgren

Glasgow-haskell-bugs mailing list

Re: Bug with readFile and named pipes

2001-08-23 Thread Thomas Hallgren

  Simon Marlow wrote:

There was a long thread about this a while back (subject Blocking I/O
and FIFOs).

I didn't find it in the archives...

  The conclusion was that the behaviour varies between OSs:
the behaviour Thomas described occurs on FreeBSD, but not Linux or
Solaris.  POSIX appears to be ambiguous on the subject.

I forgot to say that I tested my program on SunOS 5.7 (GHC 4.08 and 
5.00.1), Linux 2.2 (GHC 5.00) and Linux 2.4 (GHC 5.00.2), and the 
problem occurs in all cases. What is it that only occurs on FreeBSD?

Thomas Hallgren

Glasgow-haskell-bugs mailing list

Bug with readFile and named pipes

2001-08-21 Thread Thomas Hallgren


Programs that read from a named pipe usually block until a writer opens 
the pipe and writes something to it. The following program,

main = putStr = readFile /tmp/p

(where /tmp/p refers to a named pipe) exhibits this behavour when 
compiled with HBC or when run with runhugs, but *not* when compiled with 
GHC. Instead the program immediately exists, returning the empty string.

Tracing system calls reveals the following:

open(/tmp/p, O_RDONLY|O_NONBLOCK|O_NOCTTY) = 3
read(3, , 8192)   = 0
close(3)= 0

Apparently, opening the file in nonblocking mode has undesirable effects...

I consider this a bug and hope that it will be fixed for the 5.02 
release. Is there a simple workaround I can use in the mean time?

Thomas Hallgren

Glasgow-haskell-bugs mailing list

Re: POLL: GC options

2001-08-06 Thread Thomas Hallgren

Simon Marlow wrote:


There is some disagreement over how the GC options should be specified
for Haskell programs.

Something that I think would be very convenient, help alleviate some of 
the problems discussed, and still very easy to implement, would be 
support for setting run-time system options from an environment 
variable, GHCRTS say. That way, you wouldn't have to specify them on the 
command line *everytime *you run a program. It would allow users to run 
a shell scripts at login-time to set the heap size limit to some 
suitable value, in some platform-specific way, for example taking into 
account the amount of available RAM. An additional benefit is that if 
you call Haskell programs from shell scripts, and switch between 
different Haskell compilers (like I often do), you don't have to change 
your scripts to pass the right RTS options: they could automatically be 
taken from the right environment variable (GHCRTS, HBCRTS, HUGSRTS, 
NHC98RTS, etc)

In the fudget library, we use the following flexible scheme (*):

The /value/ of a parameter called /name/ is taken from

   1. the command line, if -/name// value/ is present, else
   2. the environment variable FUD_/prog/_/name/ (where /prog/ is
  the name of the program), if set, else
   3. the environment variable FUD_/name/, if set, else
   4. a builtin default (indicated in the tables above).

This allows users to set global defaults as well as defaults for 
particular programs.

Issue 2: Should -M be renamed to -H, and -H renamed to something else?

HBC calls these flags -h and -H. I am sure you can figure out which is 

Issue 3: (suggestion from Julian S.) Perhaps there should be two options
to specify optimise for memory use or optimise for performance,

Clever automatic GC tuning would of course be nice. The current solution 
seems to set the limit on how much can be allocated before the next GC 
based on heap residency. This lowers the performance of programs with 
low residency and fast allocation rate. Taking the ratio between GC time 
and mutator time into account could perhaps help?

Regarding the maximum heap size, to avoid letting the heap grow too 
large, you could perhaps take into account the number of page faults 
that occur during garbage collection, or the ratio between CPU time and 
real time...

Thomas Hallgren


Glasgow-haskell-users mailing list

Re: hGetContents and laziness in file io

2001-07-24 Thread Thomas Hallgren


My guess is that there is a space leak in your program. In both function 
convert and parseAll, there are references (the variable ulf) to the 
contents of the input file, and they will probably not be released until 
the functions return (unless you use a compiler that is clever enough to 
delete references after their last use...). There might be sources of 
space leaks also in the function parse that is called from parseAll.

If your program only processes one file each time you run it, you could 
structure it like this:

main = interact parseAll'
parseAll :: String - String
parseAll' = unlines . map convert' . parse'

parse' :: String - [Tree]
convert' :: Tree - String

parse' s =
  case parseOneTree s of
Good (tree,rest) - tree:parse' rest
Error err - error err

convert' tree = ...

Note that parse' is lazy: it returns the first tree before it tries to 
parse the rest of the input.

Anyway, space leaks can be hard to find and eliminate, but there are 
tools that can help. The Haskell compiler Nhc98 
( tries to generate space efficient 
code to begin with, but also provides heap profiling to help you find 
out what kind of data is occupying all the space (constructor profile), 
which functions produced the data (producer profile) which functions 
have references to the data (retainer profile), ...

Hope this helps!

Thomas Hallgren

Hal Daume wrote:

... the file that I'm working with is ~20mb of trees.  When I
run my program on this, it is unable to reclaim space (unless i set the
heap really high). ...

convert inF outF = do inH - openFile inF ReadMode
  ulf - hGetContents inH
  outH - openFile outF WriteMode
  parseAll outH ulf
  hClose inH
  hClose outH

parseAll outH ulf =
case parse s of
Good (tree, rest) - case convert tree of
 Good s'   - do hPutStrLn outFile s'
 Error err - do putStrLn err
Error err - do return ()

PLEASE help!

Haskell mailing list

Re: lexical description problem in language report?

2001-07-24 Thread Thomas Hallgren

  Wolfgang Lux wrote:

Thomas Hallgren wrote

There seems to be a similar problem with qualified identifiers. The 
production for lexeme includes varid, conid, etc, rather than qvarid, 
qconid, etc.

Sorry we must have a different version of the report, but in my copy 
and also in the version on Simon PJ's web-pages section 2.4 (in the 
last paragraph) and appendix B include productions for the qualified 

The version of the report I looked in is here:

which is probably the same one you have, so it seems I need to clarify 
what I wrote.

Although qualified names are listed in section 2.4,and in appendix B, 
the two first productions of the grammar are:

  program -  {lexeme | whitespace }
  lexeme  -  varid | conid | varsym | consym | literal | special | 
reservedop | reservedid

There is no reference to qualified names here. I thought the purpose of 
these productions were to say that a Haskell program is correct on the 
lexical level iff there is a derivation of it in the lexical grammar, 
starting from the nonterminal program. Since qualified names are not 
part of this grammar, they are not part of the lexical syntax, which 
contradicts the text in section 5.5.1.

So, I repeat my improvment suggestions: include qvarid, qconid, etc, in 
the production for lexeme. Move the explanation of the lexical 
properties of qualified names from section 5.5.1 to section 2.4.

Thomas Hallgren

Haskell mailing list

Re: lexical description problem in language report?

2001-07-23 Thread Thomas Hallgren

Memovich, Gary wrote:

 ... in section 2.3 where it is claimed that the string {- is a 
 lexeme. However the string {- cannot be produced by the given 
 grammar production.  ...

There seems to be a similar problem with qualified identifiers. The 
production for lexeme includes varid, conid, etc, rather than qvarid, 
qconid, etc. (Perhaps someone forgot to update it when qualified names 
were introduced, in Haskell 1.3...)

This might lead you to believe that qualified names are part of the 
context-free syntax rather than the lexical syntax, and hence that 
spaces are allowed in them. Qualified names are discussed briefly near 
the end of section 2.4, but their lexical properties are not explained 
here. Instead the reader is refered to section 5.3. This reference 
probably meant to lead to 5.5.1, where the text makes it clear that 
qualified names are part of the lexical syntax.

The same problem is present in Appendix B.

Suggestions: include qvarid, qconid in the production for lexeme. Move 
the explanation of the lexical properties of qualified names from 
section 5.5.1 to section 2.4.

Thomas Hallgren

Haskell mailing list

basicTypes/Var.lhs:194: Non-exhaustive patterns in function readMutTyVar

2000-11-27 Thread Thomas Hallgren


In some Haskell code I am writing at the moment I use a number of 
multi-parameter classes, with various interrelated instances. One class 
looks like

   class Convert from to where conv :: from - to

Everything works fine, but when I add functional dependencies, to reduce 
the need for type signatures,

   class Convert from to | from - to where conv :: from - to

GHC 4.08.1 fails with the message

   basicTypes/Var.lhs:194: Non-exhaustive patterns in function readMutTyVar

(I also get messages like

   zonkIdOcc:  FunDep_a1sp
   zonkIdOcc:  FunDep_a1sj
   zonkIdOcc:  FunDep_a1sg
   zonkIdOcc:  FunDep_a1s8
   zonkIdOcc:  FunDep_a1sa

but these seem to be harmless.)

Is there a fix for this already, or should I prepare a more detailed bug 

Thomas Hallgren

PS My code is accepted by Hugs...

Glasgow-haskell-bugs mailing list

Re: basicTypes/Var.lhs:194: Non-exhaustive patterns in function readMutTyVar

2000-11-27 Thread Thomas Hallgren

"Jeffrey R. Lewis" wrote:

 I'll certainly have a look, but, Thomas, I'll need more to go on.  Also, I
 wouldn't count on much from the implementation of functional dependencies
 in 4.08 - it was only partially implemented at the time that release was

I'll try to construct a small example and mail it later today.

Thomas Hallgren

Glasgow-haskell-bugs mailing list

Re: basicTypes/Var.lhs:194: Non-exhaustive patterns in function readMutTyVar

2000-11-27 Thread Thomas Hallgren

"Jeffrey R. Lewis" wrote:

 I'll certainly have a look, but, Thomas, I'll need more to go on.  Also, I wouldn't 
count on much from the implementation of functional dependencies in 4.08 - it was 
only partially implemented at the time that release was snapshotted.


Simon Peyton-Jones wrote:

 Thomas, in parallel, I'd like to get this bug into our regression test
 suite.  How hard would it be to boil down your program to something
 of modest size that still shows the bug?

As promised, here is a small example that shows the bug.

Thomas Hallgren

{- A stripped down example that causes GHC 4.08.1 to crash with:

   basicTypes/Var.lhs:194: Non-exhaustive patterns in function readMutTyVar

main = dup 1 = print

foreign import "dup" primDup :: Int - IO Int
--dup :: Int - IO Int   -- not needed with (1), needed with (2)
dup = call primDup   -- ghc crashes here with (1), ok with (2)

class Callc h | c - h where call  :: c - h-- (1) problematic
--class Callc h  where call  :: c - h  -- (2) ok

class Result  c h | c - h where fromC :: c - IO h

instance Result c h = Call (IO c) (IO h) where call f = fromC = f
instance Call c h = Call (Int-c) (Int-h) where call f = call . f

instance Result Int Int where fromC = return

The example is perhaps too stripped down to illustrate the purpose of these
classes, but the idea is that the class "Call" should relate suitably declared
low-level prim_types in foreign imports to sensible, high-level Haskell types,
allowing high level functions to be obtained by simply applying the method
"call" to the primitive function, as in the definition of dup above, without
having to explicitly give also the type of the high level function.

Re: basicTypes/Var.lhs:194: Non-exhaustive patterns in function readMutTyVar

2000-11-27 Thread Thomas Hallgren


Here is another example which GHC doesn't like.

Thomas Hallgren

module PR where

-- This accepted by Hugs, but not by GHC 4.08.1

class P a
class R a b | b-a

instance (P a,R a b) = P b

GHC 4.08.1 doesn't seem to allow variables in the context that don't appear
after the =, but which are still ok since they are determined by the
functional dependenices.

Glasgow-haskell-bugs mailing list

Re: Haskell - Java bytecode?

2000-05-24 Thread Thomas Hallgren


 To those of you who are working on implementations:
 How do you implement

 1) tail recursion
 2) polymorphism
 3) closures  eval (i.e., laziness)

One approach worth mentioning is described in

David Wakeling: "Compiling lazy functional programs for the Java Virtual
Machine", Journal of Functional Programming, Vol 9, Issue 6, Nov 1999.

The translation, which is done via the v,G-machine, is described in
detail. The article also contains performance figures with comparisons
to related implementations.

Thomas Hallgren

Re: Haskell + Functional GUIs

2000-03-14 Thread Thomas Hallgren

Miron Brezuleanu wrote:


 I'm a Haskell newbie. I'm also interested in GUIs. I've seen some nice
 stuff concerning functional programming and GUIs, but it appears to have
 been abandoned a long time ago (ie Haggis, Fudgets -- no new releases
 since 96).


Today, I put sources for Fudgets [1] version h13t on our ftp site [2]. It
compiles with HBC and GHC 4.06.

Fudgets is still maintained, although we haven't taken the time to make any
thoroughly tested releases. But it still works well enough to be used in
undergraduate teaching and in other reserch projects [3].

Thomas Hallgren


Re: Which GUI on X11R6 ?

1999-08-02 Thread Thomas Hallgren

"Wilhelm B. Kloke" wrote:


 has anybody there an idea which GUI is usable with Haskell 98 on
 a Unix/X11R6 system (FreeBSD to be complete)?

 It seems that all GUI stuff develepmont (Fudgets, Haggis ...)
 has been stalled since some years.

The fudget library still works and it has actually received various
small improvements and additions over the last couple of years. But this
work has been done as a spare time project and as needed by another
project [1], so we haven't taken the time to create and advertise any
formal releases.

Recent versions of the fudget library and the reference manual
can be found on [2] and [3], respectively. It currently compiles with
HBC for Haskell 1.4 and Haskell 98 and, occasionally also with GHC 4.0x. 



Thomas Hallgren

PS Since my home computer runs FreeBSD, I know for sure that Fudgets
compiles and runs just fine under FreeBSD :-)

Re: Modifying the monomorphism restriction

1999-02-24 Thread Thomas Hallgren

John Hughes wrote:

 Some suggest that it is enough for compilers to issue a warning when using
 call-by-name. I disagree strongly.

I agree with Johns objection to the compiler warning solution, so here is another

The monomorphism restriction makes sure that certain values are computed at most
once by restricting them to be used at only one type. Couldn't the same be
achieved by

   * getting rid the monomorphism restriction, i.e., let all definitions to be
 overloaded by default,
   * add the language implementation requirement that overloaded values should be
 computed at most once for each instance they are used at.

Advantages of this solution:

   * It solves the problem. Since all definitions can be overloaded, definitions
 that today need the eta expansion fix, or the type signature fix, will work
 without the fix.
   * We have semantic backwards compatibility. For those programs that depend on
 the monomorphism restriction for efficiency, this solution should give the
 same efficiency.
   * We have syntactic backwards compatibility. No syntactic change is needed.
   * We get more consistent uses of type signatures. Type signatures are only
 used to restrict types, not to make them more general. (This means for
 example that a type signature that was added for documentation purposes can
 always be commented out if types change a lot during program development...)

One question then is how feasible this is to implement. But isn't this what you
get in implementations that resolve overloading at compile time rather than by
passing dictionaries at run time? Hasn't this been tried already (In GHC? In
Hugs?) and found to be feasible? (The reason it might not be feasible is that you
can get a code explosion, possibly an infinite one.)

Have I missed something fundamental that prevents this solution from working?

Thomas Hallgren

Re: Haskell-2

1999-02-19 Thread Thomas Hallgren

Jose Emilio Labra Gayo wrote:

  I agree; Haskell 2 should have existential (and universal) types.  I
  also think it should have both extensible records and extensible
  variants.  (See the following paper for more information on these.
  TREX is an implementation of half of this system; it has the
  extensible records but not extensible variants.)
  Carl Witty
 Just a question, Is there anyone trying to implement extensible variants?

Johan Nordlander has developed a type system which allows subtyping on both
records and variants, at the same time as it stays very close in spirit to
the convetional Hindley/Milner types system. It is described in a ICFP'98
paper. You can get it from

There is also ongoing work on an implementation of a version of Haskell,
called OHaskell, which incoropates this type system.

Mvh Thomas H

Pattern matching bug?

1999-02-08 Thread Thomas Hallgren


I enclose a small program that causes ghc 4.01 to say "panic! (the
`impossible' happened)". I also supply the output from ghc -v.

Thomas Hallgren

module GhcBug where

data E = B { a,b,c,d,e,f::Bool }

bug x =
  case x of
-- alt 1 and alt 2 should be equivalent
B _ _ _ _ True False - undefined -- alt 1, problematic
--B {e=True,f=False} - undefined -- alt 2, no problem

B {b,f=False,e=False} - undefined

The Glorious Glasgow Haskell Compilation System, version 4.01, patchlevel 0

Effective command line: -v

Ineffective C pre-processor:
echo '{-# LINE 1 "GhcBug.hs" -}'  /tmp/ghc23829.cpp  cat GhcBug.hs  

sys 0.0
ghc-4.01:compile:Output file GhcBug.o doesn't exist
ghc-4.01:compile:Interface file GhcBug.hi doesn't exist
ghc-4.01:recompile:Input file GhcBug.hs newer than GhcBug.o

Haskell compiler:
/usr/pd/lib/ghc-4.01/hsc ,-W ,/tmp/ghc23829.cpp  -fignore-interface-pragmas 
-fomit-interface-pragmas -fsimplify [  -ffloat-lets-exposing-whnf -ffloat-primops-ok 
-fcase-of-case -fdo-case-elim -freuse-con -fpedantic-bottoms 
-fmax-simplifier-iterations4  ]   -fwarn-overlapping-patterns -fwarn-missing-methods 
-fwarn-duplicate-exports -fhi-version=401 
-himap=.%.hi:/usr/pd/lib/ghc-4.01/imports/std%.hi   -v -hifile=/tmp/ghc23829.hi 
-C=/tmp/ghc23829.hc -F=/tmp/ghc23829_stb.c -FH=/tmp/ghc23829_stb.h +RTS -H600 
Glasgow Haskell Compiler, version 4.01, for Haskell 1.4

panic! (the `impossible' happened):
Check.check': Not implemented :-(

Please report it as a compiler bug to [EMAIL PROTECTED]

sys 0.0
deleting... /tmp/ghc23829.cpp /tmp/ghc23829.hi /tmp/ghc23829.hc /tmp/ghc23829_stb.c 

rm -f /tmp/ghc23829*

Buggy implementation of exististential types?

1999-02-08 Thread Thomas Hallgren


I enclose a small program that crashes with "segmentation fault" when
compiled with ghc 4.01. It makes use of existential quantification in
data types, which I suspect is the cause of the problem.

I also supply the output from ghc -v.

The program was compiled and run on a macine with the following uname -a

SunOS 5.6 Generic_105181-11 sun4u sparc

and gcc -v gives

Reading specs from
gcc version 2.8.1

This may look a little ad hoc, but when I tried our normal installation
of gcc,

Reading specs from
gcc version 2.8.1

all programs crashed with "bus error"...

Thomas Hallgren

-- This program crashes with "segmentation fault".

main = print xs

xs = [C False] -- ++ [C "Hej", C (3,4)]

data T = forall a . (Show a) = C a
instance Show T where showsPrec n (C a) = showsPrec n a

--data T = forall a . C (a-String) a -- this causes problems too

--data T a = C a deriving (Show) -- no problem...

The Glorious Glasgow Haskell Compilation System, version 4.01, patchlevel 0

Effective command line: -v

Ineffective C pre-processor:
echo '{-# LINE 1 "tstExist2.hs" -}'  /tmp/ghc26260.cpp  cat tstExist2.hs  

sys 0.0
ghc-4.01:compile:Output file tstExist2.o doesn't exist
ghc-4.01:compile:Interface file tstExist2.hi doesn't exist
ghc-4.01:recompile:Input file tstExist2.hs newer than tstExist2.o

Haskell compiler:
/usr/pd/lib/ghc-4.01/hsc ,-W ,/tmp/ghc26260.cpp  -fignore-interface-pragmas 
-fomit-interface-pragmas -fsimplify [  -ffloat-lets-exposing-whnf -ffloat-primops-ok 
-fcase-of-case -fdo-case-elim -freuse-con -fpedantic-bottoms 
-fmax-simplifier-iterations4  ]   -fwarn-overlapping-patterns -fwarn-missing-methods 
-fwarn-duplicate-exports -fhi-version=401 
-himap=.%.hi:/usr/pd/lib/ghc-4.01/imports/std%.hi   -v -hifile=/tmp/ghc26260.hi 
-C=/tmp/ghc26260.hc -F=/tmp/ghc26260_stb.c -FH=/tmp/ghc26260_stb.h +RTS -H600 
Glasgow Haskell Compiler, version 4.01, for Haskell 1.4

sys 0.1

Pin on Haskell consistency info:
echo 'static char ghc_hsc_ID[] = "@(#)hsc tstExist2.hs  40.0,,";'  

sys 0.0
*** New hi file follows...
__interface Main 401 where
import IO 1 :: print 1;
import PrelBase 1 :: _dShow0 1 _dShow1 1 _dShow2 1 _dShowBool0 1 _dShowChar0 1 
_dShowInt0 1 _mshowList 1 addr2Integer 1 foldr 1 int2Integer 1 integer_0 1 integer_1 1 
integer_2 1 integer_m1 1 Show 1 String 1;
import PrelIOBase 1 :: IO 1;
import PrelNum 1 :: _dShowInteger0 1;
import PrelNumExtra 1 :: _dShowDouble0 1;
import PrelPack 1 :: packCString# 1 unpackAppendCString# 1 unpackCString# 1 
unpackFoldrCString# 1 unpackNBytes# 1;
__instimport IO ; __instimport PrelAddr ; __instimport PrelArr ; __instimport 
PrelBounded ; __instimport PrelCCall ; __instimport PrelForeign ; __instimport 
PrelIOBase ; __instimport PrelNum ; __instimport PrelNumExtra ; __instimport PrelTup ;

__export Main main xs T{C};
instance {PrelBase.Show T} = _dShowT0;
data T = __forall [_r3C] {PrelBase.Show _r3C} = C _r3C ;
main :: PrelIOBase.IO PrelBase.() ;
xs :: [T] ;
_dShowT0 :: {PrelBase.Show T} ;

ghc-4.01: module version changed to 1; reason: no old .hi file

Replace .hi file, if changed:
cmp -s Main.hi /tmp/ghc26260.hi-new || ( rm -f Main.hi  cp 
/tmp/ghc26260.hi-new Main.hi )

sys 0.0

C compiler:
gcc -v  -S -Wimplicit -O-I. -I/usr/pd/lib/ghc-4.01/includes 
-I/usr/pd/lib/ghc-4.01/includes ghc26260.c  /tmp/ghc26260.ccout 21  ( if [ 
ghc26260.s != /tmp/ghc26260_o.s ] ; then mv ghc26260.s /tmp/ghc26260_o.s ; else exit 0 
; fi )
Reading specs from 
gcc version 2.8.1
 /usr/pd/gnu/lib/ada/3.10p/lib/gcc-lib/sparc-sun-solaris2.6/2.7.2/cpp -lang-c -v -I. 
-I/usr/pd/lib/ghc-4.01/includes -I/usr/pd/lib/ghc-4.01/includes -iprefix 
 -undef -D__GNUC__=2 -D__GNUC_MINOR__=8 -Dsun -Dsparc -Dunix -D__svr4__ -D__SVR4 
-D__GCC_NEW_VARARGS__ -D__sun__ -D__sparc__ -D__unix__ -D__svr4__ -D__SVR4 
-D__GCC_NEW_VARARGS__ -D__sun -D__sparc -D__unix -Asystem(unix) -Asystem(svr4) 
-Acpu(sparc) -Amachine(sparc) -D__OPTIMIZE__ -Wimplicit ghc26260.c /tmp/ccmEEUh_.i
GNU CPP version 2.7.2 (sparc)
#include "..." search starts here:
#include ... search starts here:

Re: how about main :: IO Int

1997-08-22 Thread Thomas Hallgren

Christian Sievers wrote:

 Hello, I just wondered if it was ever considered to let the main function
 have the type IO Int, in order to let the haskell programm be able to
 return an exit code to the calling environment, as C's  int main(...)
 does. I think real programms sometimes want to  exit(1)  in some

Real programmers can do this already. They simply use the standard library
function System.exitWith [1]. I don't like the idea of changing the type of
main to IO Int for several reasons...

Thomas Hallgren


Re: Lexer/Parser for Haskell in Haskell?

1997-07-08 Thread Thomas Hallgren at home

Graeme Moss wrote:
 Has anyone written a parser for Haskell 1.4 in Haskell 1.4?

 Has any compiler written the lexer/parser in Haskell?

Nhc13 [1] by Niklas Rojemo contains both a lexer and a parser
for/in Haskell 1.3. (The differences between 1.3 and 1.4 are small [2].)
The parsing combinators and their efficiency are discussed in Rojemo's
thesis [3].

Thomas H


The Haskell 1.3 compiler NHC13 is now available

1996-11-09 Thread Thomas Hallgren at home

Version 0.0 of NHC13, Nearly a Haskell 1.3 Compiler, by Niklas Rojemo,
is now available for download from

It has the following features

- Compiles Haskell 1.3
- Supports Fudgets
- Supports several kind of heap profiles:
combinations of the above

Although NHC13 0.0 is probably not yet to be regarded as a mature
Haskell 1.3 compiler, it may still be of interest since it provides
some new kinds of heap profiles not found in any other Haskell 1.3
compiler. Finding space leaks or other undesired space behaviour using
(combinations of) retainer and biographical profiles can be much
simpler than with the traditional producer/constructor profiles.

Heap profiling also works for Fudgets programs.

The commands to use are

nhc13   the compiler
nhc13make   a version of hbcmake for nhc13
nhc13xmake  to compile Fudgets programs
hp2graphto convert heap profiling output to postscript

Manual pages with more details are included in the distributions.

Recent papers on heap profiling are

   Niklas Rojemo and Colin Runciman: "Lag, drag, void and use -
heap profiling and space-efficient compilation revisited".
In the proceedings of ICFP'96.

   Colin Runciman and Niklas Rojemo: "Two-pass heap profiling: a matter
of life and death". In the proceedings of IFL'96.

These are available from

Niklas Rojemo
Thomas Hallgren

New release of Fudgets available

1996-11-06 Thread Thomas Hallgren

?  ?

 F U D G E T S

  version h12

 The Fudget library is a toolkit for concurrent programming
 of graphical user interfaces, client/servers and more in

 The Fudgets GUI toolkit is implemented in a purely functional
 way in Haskell, without using state, threads or other
 extensions for concurrency or imperative programming.

 The big news in this release is that the interfaces to the
 X Window system and networking facilities have been ported to
 two new Haskell compilers. Fudgets thus now work with three
 different Haskell 1.3 compilers: HBC, GHC and NHC13.

 The new release is now available from the Fudgets Home Page
 on WWW

 and also via anonymous FTP on 

 in directory


 Send bug reports and feedback to 


 Thomas Hallgren
 Magnus Carlsson

?  ?

Re: Preliminary Haskell 1.3 report now available

1996-03-07 Thread Thomas Hallgren

First, I am happy to see that Haskell 1.3, with its many valuable
improvements over Haskell 1.2, is finally getting ready,
but I also have a comment:

In the syntax for labeled fields (records) the symbol - is chosen
as the operator used to associate a label with a value in
constructions and patterns:

data Date = Date {day, month, year :: Int}

today = Date{day - 11, month - 10, year - 1995}

According to a committee member, there were no convincing reasons
why - was chosen. Other symbols, like = and := were also considered.

Here are some (in my opinion) good reasons for using = instead of - :

1. In ordinary declarations, :: is used to specify the type of a name
   and = is used to specify its value:

day, month, year :: Int
day = 11; month = 10; year = 1995

   so for consistency I think the same notations should be used
   inside record values:

data Date = Date {day, month, year :: Int}
date :: Date
date = Date {day = 11, month = 10, year = 1995}

2. The - symbol is used also in list comprehensions and the new
   monad syntax ('do'):

[ 2*x | x - [1..10] ]

do c - getChar; putChar c

   In these uses of - the name on the lhs does not have the same
   type as the expression on the rhs (above, x::Int, but [1..10]::[Int]
   and c::Char but getChar::IO Char). The value that the lhs name
   (or, indeed, pattern) is bound to is "extracted" from the value
   of the rhs expression. This is very different from what happens
   with field labels, so a difference in syntax is motivated.

Sadly, I suspect it would be difficult to convince the committee to
change their minds about this at this late stage, but I am sure it
would be even more difficult to change it for a later version of


Thomas Hallgren

New release of Fudgets available

1995-07-05 Thread Thomas Hallgren


 version h9

The Fudget library is a toolkit for concurrent programming of
graphical user interfaces, client/servers and more in Haskell.

The Baastad Spring School Release is now available via WWW on

and also via anonymous FTP on 

in directory


Bug reports and feedback to 


Thomas Hallgren
Magnus Carlsson

New release of Fudgets available

1995-07-05 Thread Thomas Hallgren


 version h9

The Fudget library is a toolkit for concurrent programming of
graphical user interfaces, client/servers and more in Haskell.

The Baastad Spring School Release is now available via WWW on

and also via anonymous FTP on 

in directory


Bug reports and feedback to 


Thomas Hallgren
Magnus Carlsson

Re: Subtypes

1992-07-23 Thread Thomas Hallgren

Rob Turner [EMAIL PROTECTED] writes:

| How do you get a subtype in Haskell (or any other functional language
| come to that)? I'm thinking along the lines of (pseudo-notation):
| type weekday = {Mon, Tue, Wed, Thur, Fri}
| type weekend = {Sat, Sun}
| type day = weekend + weekday
| It springs to mind that this kind of problem is possibly solved by
| inheritance in the class system, but that only works for pre-defined
| classes. Or does it?
| Maybe subtypes don't fit elegantly into the functional model. Maybe
| they aren't necessary anyway.
| Thoughts appreciated.
| Rob

This is interesting. I don't know if there is a nice way of doing this
in Haskell. I've been looking for ways to extend ML with some kind of
subtype/supertype declarations, similar to what you suggest in your
example. What I want to achieve is subtypes based on variant types
as in the langauge Fun, described by Cardelli  Wegner in [1]
(recommended reading for anyone interested in polymorphism, subtypes
and similar type system related issues).

A variant type in Fun is an enumeration of tagged types, enclosed in
square brackets. For example, an element in the type

[ a:Int, b:Bool ]

is either an integer labelled "a" (e.g. [a=5]), or a boolean labelled "b"
(e.g. [b=false]). The subtype relation is defined as follow on variant
types (where : denotes the subtype relation):

t1:u1 ... tn:un
-- (nm)
[l1:t1, ..., ln:tn] : [l1:u1, ... ln:un, ..., lm:um]

For example [a:Int] : [a:Int, b:Bool].

To make this carry over to ML, the idea is to view data types in ML as
analogous to (named) variant types. For example the type
[ a:Int, b:Bool ] would correspond to

datatype T = a of Int | b of Bool

You can now imagine a new kind of declarations to obtain subtypes or
supertypes, by adding or removing constructors to an existing type, like
for example

subtype U : T = a of Int

One can also imagine forming supertypes by taking unions of existing
types, like in the weekday  weekend example. (Exactly what kind of
declaration you should have, and what they should look like, is mainly
a pragmatical problem, I assume.)

The subtype declarations should also extend to parameterized types,
just like it does in Fun.  For example I think it would be nice to be
able to declare a type for non-empty lists, as a subtypes of ordinary

datatype 'a list = nil | cons of 'a * 'a list
subtype 'a non_empty_list : 'a list = cons of 'a * 'a list

Introducing subtype declarations of this kind causes a number of
problems. I am primarily interested in problems concerning the type
system and type inference.

Does anyone know if someone already has done something like this, or
where to look for possible solutions?

I have tried to use the type system (and type inference algorithm)
described by Fuh  Mishra in "Type Inference with Subtypes" [2,3], but
their system allows relations only between nullary type constructors
(like for example int:real), and so wouldn't allow the non-empty list
type in the example above. The system could possibly be extended to
allow relations between arbitrary type constructors of the same arity
(has anybody done this?), but there are some other problems, concerning
what type to assign to constructors and how to type case expressions,
which I don't know how to solve.

I have also considered using the type system described by Mishra 
Reddy in "Declaration-free type checking" [4], which provides the kind
of subtype relation I want. The type inference algorithm described in
this paper works only for first-order languages, but the authors
mentions working on an extension for higher-order languages, to be used
in a language called FEL. Does anyone know if this work was

If you have an answer to any of these questions, or know where to look
for answers, or have any other comments, please email me! I'll post
a summary of the replies I get.

Thanks in advance.

Thomas Hallgren



[1] Luca Cardelli  Peter Wegner: "On Understanding Types, Data
Abstraction and Polymorphism", in Computing Surveys 17, 1985

[2] You-Chin Fuh  Prateek Mishra, "Type Inference with Subtypes",
Proc. European Symposium on Programming, 1988

[3] You-Chin Fuh  Prateek Mishra, "Polymorphic Subtype Inference,
Closing the Theory-Practice Gap", TAPSOFT 1989, LNCS vol 352

[4] Prateek Mishra  Uday S. Reddy, "Declaration-free type checking',
PoPL, 1984