Re: [Haskell] ANNOUNCE: binary: high performance, pure binary serialisation

2007-01-31 Thread Stefan Karrmann
Dear Donald!

Donald Bruce Stewart (Fri, Jan 26, 2007 at 01:51:01PM +1100):
 Binary: high performance, pure binary serialisation for Haskell
  -- 
[..]
 Encoding and decoding are achieved by the functions:
 
 encode :: Binary a = a - ByteString
 decode :: Binary a = ByteString - a
 
 which mirror the read/show functions. Convenience functions for serialising to
 disk are also provided:

How can you detect that a decode fails? Do you need to catch an error in the
IO monad?

How can you know that there is remaining input in the ByteString?

Regards,
-- 
S.Karrmann

The truth of a proposition has nothing to do with its credibility.  And
vice versa.
___
Haskell mailing list
Haskell@haskell.org
http://www.haskell.org/mailman/listinfo/haskell


Re: [Haskell] Re: state of HaXml?

2007-01-06 Thread Stefan Karrmann
My 2 cent:

Why does seq not help? See code below.

Simon Marlow (Thu, Jan 04, 2007 at 03:08:45PM +):
 and the original code was this:
 
   load fn = do handle - IO.openFile fn IO.ReadMode
contents - IO.hGetContents handle
IO.hClose handle
return $ XP.xmlParse fn contents
 
 Sure, you can replace the openFile/hGetContents pair by readFile, but the 
 real problem is the presence of the hClose.  Removing that will solve your 
 problem (but note that you now have no control over when the file is 
 actually closed).

load fn = do handle - IO.openFile fn IO.ReadMode
 contents - IO.hGetContents handle
 let res = XP.xmlParse fn contents
 seq res $ IO.hClose handle -- maybe use deepSeq
 return $ res

load fn = do handle - IO.openFile fn IO.ReadMode
 contents - IO.hGetContents handle
 let len = length contents
 seq len $ IO.hClose handle
 return $ XP.xmlParse fn contents

Cheers,
-- 
Stefan

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


[Haskell] ANN: monadic probabilistic functional programing

2006-07-21 Thread Stefan Karrmann
Dear all,

the library PFP by Martin Erwig is quite useful for probabilistic
calculations. I have extended it to abstract monads, cabal and darcs,
confer [1].

I cannot find a licence or legal note on the page of Martin Erwig.
Therefore, I can legally only publish a patch. Unfortunatly, darcs does
not provide a method to extract patches as far as I know. (Hints are
welcomed.) As a result you can download a stripped down version of my darcs
repository from [1]. How to create the complete repository is there
described, too.

[1] http://home.arcor.de/s.ka/haskell/pfp.html

Kind regards,
-- 
Stefan Karrmann
___
Haskell mailing list
Haskell@haskell.org
http://www.haskell.org/mailman/listinfo/haskell


Re: [Haskell] Package mounting proposal

2006-07-21 Thread Stefan Karrmann
My 2 cents:

Sven Moritz Hallberg (Sun, Jul 16, 2006 at 01:24:43AM +0200):
 [...]
 She must specify it somehow. Two possibilities come to mind:
 
   1. Add a field to the package description of foo (v1.4, say) that says
  I'm backwards-compatible with 1.3. When building, this relation
  would have to be inspected to see whether any currently installed
  version of foo satisfies the dependency specified by the mount.
   2. Declare a convention for version numbers to carry compatibility
  information, like the OpenGL standard, for example: If the new
  version is backwards-compatible, only the minor version number
  changes. If it isn't, the major version number must be incremented.
 

I prefer 1. The FSF use 2 for its GNU software and others started with it,
too. But after a while most of them tend to increase major numbers. E.g.
3.0, 3.11, 95, 98, 2000

Regards,
-- 
Stefan Karrmann

If A equals success, then the formula is _A = _X + _Y + _Z.  _X is work.  
_Y
is play.  _Z is keep your mouth shut.
-- Albert Einstein
___
Haskell mailing list
Haskell@haskell.org
http://www.haskell.org/mailman/listinfo/haskell


Re: [Haskell] ANN: monadic probabilistic functional programing

2006-07-21 Thread Stefan Karrmann
Dear all,

I have renamed all files. Because of this the darcs diff contains *all*
source lines. Then it is not only a patch but also the complete original
work. Moreover, the patch does not contain a move from or unlink of the old
locations.

Taral (Fri, Jul 21, 2006 at 11:22:22AM -0500):
 On 7/19/06, Stefan Karrmann [EMAIL PROTECTED] wrote:
 Unfortunatly, darcs does
 not provide a method to extract patches as far as I know. (Hints are
 welcomed.)
 
 darcs diff and darcs annotate.

Regards,
-- 
Stefan Karrmann
___
Haskell mailing list
Haskell@haskell.org
http://www.haskell.org/mailman/listinfo/haskell


Re: [Haskell] Re: QuickCheck revival and Cabal

2006-04-14 Thread Stefan Karrmann
Koen Claessen (Wed, Apr 12, 2006 at 11:06:50AM +0200):
 There is currently an old QuickCheck version in the standard hierarchy
 in Test.QuickCheck. As the new QuickCheck is incompatible with the old
 one, I do not want to override that place. Rather, I would like to
 create my own little space in the hierarchy where the new version can
 sit and develop.
 
 If you intend the new version as a replacement for the old, then it 
 should be called Test.QuickCheck, and the package should identify itself 
 as a newer version (2.0, or whatever).  It's possible to have multiple 
 versions of a package simultaneously installed (at least with GHC). 
 Currently it isn't possible to use them both in the same program, but we 
 intend to allow that in the future.
 
 The new QuickCheck is not a replacement for the old. For one, it is 
 incompatible (in some trivial ways, but still). I don't want peoples 
 programs or other libraries to break just because they rely on the old 
 QuickCheck.

An increase in the major version number used to show that the new version
is incompatible with the old one. Extensions left the major version number
unchanged and increase the minor version number.

major change : 1.0   - 2.0
minor change : 1.0   - 1.1
bugfix change: 1.0.0 - 1.0.1

So a Cabal package QuickCheck-2.0 should be ok. If you install it, you
should expect incompatibilities.

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


[Haskell] Compilation of big, computed tables

2006-02-22 Thread Stefan Karrmann
Dear all,

can ghc compile huge tables into efficient code if they are constant at
compile time?

Two examples may clearify the question:

big1 :: UArray Int Char
big1 = array (0,1000) $! map (\i - (i,toEnum i)) [0..1000]

big2 = sum [0..1]::Int -- == 50005000 == n*(n+1)/2 where n = 1

Both values are constant at compile time. As they are given by pure
functions, the compiler could evaluate them and write the *result* into the
object file 'foo.o'. This would save code size and run time.
I peeked into 'foo.hc' but I didn't found 0x2fb0408 nor an array {0, 1, 2,
3, ..., 1000} or similar things.


The function in big2 should show that the computation of the value could be
very time consuming. If the compiler does not compute it, the source file
could be generated by a helper program (or template Haskell?).

The function in big1 should show that the conversion of the data into an
array could be run-time, code-size and heap-size consuming. (You need the
list (maybe explicitly - think of 1000 fixed pseudo-random numbers) and
convert it into an array.) If the compiler generates the unboxed array
directly it could be rather efficient.


PS: I compiled with: ghc6 -c -O2 -keep-tmp-files -keep-hc-files foo.hs

Regards,
-- 
Stefan Karrmann
module Foo (module Foo) where

import Data.Array.IArray
import Data.Array.Unboxed

big1 :: UArray Int Char
big1 = array (0,1000) $! map (\i - (i,toEnum i)) [0..1000]

big2 = sum [0..1]::Int

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


Re: [Haskell] Improvements to GHC

2005-11-23 Thread Stefan Karrmann
My 2 cents:

John Lask (Thu, Nov 17, 2005 at 08:57:52AM +1030):
 I would like to sound out the Haskell community on what the feeling are 
 most desirable to improve the commerciality (i.e. its general use) of ghc 
 and Haskell in general (as distinct from feature set)
 
 3) Macro / conditional compilation / compiler meta language / additional 
 binding forms
These are perhaps distinct issues but can be discussed together.
The prevalent use of #ifdef and the cpp is indicative of the general 
 need to have some standard means by
which differences between compilers ghc/hugs/nhc can be accommodated for 
 in the source code.
To date this issue has not been tackled in any meaningful way, perhaps 
 we can continue
 to use cpp but for the sake of portability
 
 A means of defining additional binding forms would be nice as it would 
 further facilitate embedded dsl
 for which Haskell is pre-eminent, and which use is a great motivator 
 for venturing into
 Haskell in the first place.

The macro languages tend to become more and more complex over time.
Eventually, you have two complex languages. First, a Haskell Macro
Language, second Haskell.

Why can we not use staging like in Omega, cf. [1], or Template Haskell?
Maybe Haskell itself can generate the compiler and system specific source?

[1] http://www.cs.pdx.edu/~sheard/Omega/index.html

Regards,
-- 
Stefan Karrmann
___
Haskell mailing list
Haskell@haskell.org
http://www.haskell.org/mailman/listinfo/haskell


Re: [Haskell] rfc: package mounting

2005-06-23 Thread Stefan Karrmann
My two cents:

In Coq, cf. http://pauillac.inria.fr/coq/doc8/main.html chapter 2.5.1
(Names of libraries and files), there is something similar:

Add LoadPath physical_path as dirpath.

E.g.:

Add LoadPath /home/sk/lib/foo as Foo.

Frederik Eaton (Thu, Jun 23, 2005 at 02:14:00AM -0700):
 Hi all,
 
 It looks like there's been a bit of recent discussion regarding module
 and package namespaces. There is a certain possible design feature
 that I don't think has been mentioned yet, that I think would be very
 helpful, so I thought I should at least bring it up.
 
 What I want is to be able to build a module namespace for a program
 out of packages in much the same way that filesystem namespaces are
 built, namely with mounting operations, rather than just by union or
 overlay operations as in the status quo. In other words I would like
 to be able to specify along with the -package option a mount point
 for that package in the module namespace. One possible option syntax
 might be e.g. -package my-graphics-lib -package-base
 Graphics.UI.MyGraphicsLib. (Also, for backward compatibility and
 convenience, packages should probably be able to specify a default
 mount point, to allow existing compiler command-line syntax to be
 used.)
 
[...]
 
 Frederik

Regards,
-- 
Stefan Karrmann
___
Haskell mailing list
Haskell@haskell.org
http://www.haskell.org/mailman/listinfo/haskell


Re: [Haskell] instance Bounded Double

2005-03-14 Thread Stefan Karrmann
John Meacham (Sun, Mar 13, 2005 at 08:08:56PM -0800):
 On Sun, Mar 13, 2005 at 11:08:26PM +, Thomas Davie wrote:
  [...] We could define maxBound as 
  (2^(mantisa_space))^(2^(exponent_space)) and min bound pretty 
  similarly... But I'm sure that everyone will agree that this is a 
  horrible hack.

2 cent:

module Float_bounds
   ( max_float
   , min_float
   , min_pos_float
   , max_neg_float
   ) where

d = 1 :: Double
f = 1 :: Float

max_float x = encodeFloat (radix ^ mant - 1) (expo - mant)
   where radix = floatRadix x
 mant  = floatDigits x
 expo  = snd $ floatRange x

min_pos_float x = encodeFloat (1) (expo - mant)
   where radix = floatRadix x
 mant  = floatDigits x
 expo  = fst $ floatRange x

min_float x = - max_float x
max_neg_float x = - min_pos_float x

Regards
-- 
Stefan Karrmann
___
Haskell mailing list
Haskell@haskell.org
http://www.haskell.org/mailman/listinfo/haskell


[Haskell] Non-terminating compilation of non-positive construction.

2004-09-05 Thread Stefan Karrmann
Hi,

in Coq (cf. http://pauillac.inria.fr/coq/coq1-eng.html) inductive and
coinductive (aka lazy) types are restricted by the positivity condition
(cf. http://pauillac.inria.fr/coq/doc8/Reference-Manual006.html#htoc91).

My first try to violate this condition in Haskell is:
---
module Limits (module Limits) where

import qualified Prelude$
$
data False = False !False
   deriving (Prelude.Show)
-- Approximation of: data False = {- no Value -}
-- The lazy variant has the same result.
-- Of course there is: f = False f

data Non_positive = Non_pos (Non_positive - False)

app :: Non_positive - Non_positive - False
app f x = case f of
   Non_pos h - h x

delta :: Non_positive
delta = Non_pos (\ x - app x x)

-- Up to this definition ghc terminates.

-- (\x - x x) (\x - x x)
loop :: False
loop = app delta delta


The compilation by the Glorious Glasgow Haskell Compilation System,
version 6.2, loops on this small module. IMHO only the execution should
loop or non positive constructions should be excluded.

Is it a bug or is non positivity too dangerous?

Sincerly,
-- 
Stefan Karrmann
___
Haskell mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell


Re: time since the epoch

2003-11-13 Thread Stefan Karrmann
Dear Juanma,

thanks for your remarks.

Juanma Barranquero (Mon, Nov 10, 2003 at 10:54:22AM +0100):
 On Fri, 7 Nov 2003 19:55:47 +0100
 Stefan Karrmann [EMAIL PROTECTED] wrote:
 
  I've inserted 'convert = (uncurry cFromTai) . cToTai'.
 
 Great, thanks.
 
  A fixed and checked version is appended and carbon copied to  
  [EMAIL PROTECTED]. 
 
 What's haskell-libs-developers? I thought libraries' development was
 carried over on [EMAIL PROTECTED] (And shouldn't we be discussing
 Tai.lhs there, BTW :)

Well, the original thread was on this list. I'm moving it to
[EMAIL PROTECTED] now.

 I'm attaching a patch (diff -u2) with a few small changes:

I've included it.

 More coments:
 
  - I'm sending you the patch throw the Haskell list because previous
attempts of sending to your e-mail address failed.

I'm using ASK as a spam killer. Do you have problems with it?

  - Are you very fond of the literate style? I ask because unlit'ing it
would allow adding Haddock coments, which would be nice.

I've given it a try, but my comment marking could be improved.

  - I'm not sure I like depending on a leapseconds table hardcoded in the
source, even if it changes slowly. Wouldn't it be better to have the
data in a file and load it through unsafePerformIO? (And isn't
loading configuration data one of the few good examples of use of
unsafePerformIO, after all? :)

Well, I included the two as examples. The empty one is correct for all
times before 1970-01-01. That's more than ten billion years.

  - I get a warning with -Wall:
 
 Warning: Defined but not used:
TimeDiff, days_from_MJD2unixEpoch, days_from_unixEpoch2MJD',
hours_per_day, isodelta, isomoveDHM, isomoveS, isomoveYM,
libtaiEpoch, month_per_year, test, test2

Some values are only for testing and debugging while others are
experimental, e.g. TimeDiff and friends.

Several of these are neither used nor exported. ???

Regards,
-- 
Stefan Karrmann
Bitte bzip2 benutzen!
___
Haskell mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell


Re: set representation question

2003-11-12 Thread Stefan Karrmann
Dear Nicholas,

Nicholas Nethercote (Wed, Nov 12, 2003 at 11:32:54AM +):
 On Wed, 12 Nov 2003, Tom Pledger wrote:
 
  Hal Daume III writes:
   :
   | *all* i care about is being able to quickly calculate the size of
   | the intersection of two sets.  these sets are, in general, very
   | sparse, which means that the intersections tend to be small.
   |
   | for example, i might have two sets reprsented by the arrays:
   |
   |  {0,1,10,346,398,1039,3289,3853,9811,89231,50913}
   |  {0,3,98,183,398,1038,5319,7642,9811,13893,93123}
   |
   | and all i need to be able to do is respond with 3 very very
   | quickly.  using sorted arrays, this takes O(n+m) time (where n and
   | m are the sizes of the arrays).
 
  The total time (including the up front time for building the data
  structure) can't go below O(n+m), because if it did, you'd be
  neglecting to look at some of the elements at all.
 
 Isn't it O(min(m,n))?  You don't have to look at all elements for the
 intersection.  Eg:
 
   {0,1,10}
   {0,3,98,183,398,1038,5319,7642,9811,13893,93123}

O(f) describes the worst case of the algorithm. It is O((m,n)-m+n).
The average cost may be lower, but it depends on the distribution of the
data.

Sincerly,
-- 
Stefan Karrmann
___
Haskell mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell


Re: time since the epoch

2003-11-07 Thread Stefan Karrmann
Dear Juanma, 
 
some last moment changes broke the library, I am sorry.  
 
Juanma Barranquero (Thu, Nov 06, 2003 at 05:03:03PM +0100): 
  
 On Sat, 1 Nov 2003 17:36:11 +0100 
 Stefan Karrmann [EMAIL PROTECTED] wrote:  
  
  a while ago time calculation was subject on this list. 
  Now, I have a time library based on the TAI (international 
  atomic time) time scale.  
  
 I get the following error with GHCi: 
  
  
  
 Compiling Main ( Tai.lhs, interpreted ) 
  
 Tai.lhs:450: 
 Couldn't match `LeapSeconds' against `TAI' 
 
 Also, wouldn't make sense to add:
 
 cConvert :: (Calendar a, Calendar b) = a - b
 cConvert = cFromTai . cToTai

I've inserted 'convert = (uncurry cFromTai) . cToTai'.

A fixed and checked version is appended and carbon copied to  
[EMAIL PROTECTED]. 
 
Regards, 
--  
Stefan Karrmann 



Tai.lhs.bz2
Description: Binary data
___
Haskell mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell


Re: time since the epoch

2003-11-02 Thread Stefan Karrmann
Hi,

a while ago time calculation was subject on this list.
Now, I have a time library based on the TAI (international
atomic time) time scale.

Peter Thiemann (Thu, Feb 06, 2003 at 12:40:14PM -0800):
 John's code illustrates TimeDiff's deficiencies perfectly:
 
 There is also a more fundamental problem with the TimeDiff data
 type. While seconds, minutes, hours, and days are clearly specified
 amounts of time, the duration of a month or a year may vary depending
 on the reference point where the time difference is applied.

 newtype TimeDiff = TimeDiff Rational
deriving (Eq, Ord)
 Hmm, this is underspecified!
 As another poster said, (pointing out http://cr.yp.to/libtai, but it
 is better to look at http://cr.yp.to/time.html, which has a discussion
 on UTC vs TAI vs UNIX time) the official source of time is TAI, so it
 is best to base a time library
 *on the number of TAI seconds since a reference date*
 (which is btw what the libtai is all about).
 For compatibility with UNIX time, Arthur David Olson's popular time
 library uses an epoch of 1970-01-01 00:00:10 TAI
 [http://cr.yp.to/proto/utctai.html]. 
 So this mostly means that you need to set your system clock correctly:-)

Sincerly,
-- 
Stefan Karrmann
2003 Copyright (C) Stefan Karrmann [EMAIL PROTECTED]
All rights reserved.
The rights of the GNU Library General Public Licence Version 2
are granted, for details confer http://www.fsf.org/copyleft/lgpl.html.

This module provides data structures and functions to calculate with
Temps Atomique International (International Atomic Time, short TAI).
For further information about time see, e.g.
http://www.boulder.nist.gov/timefreq/general/glossary3.htm.

 module Main
 (
   --main,
   TAI(TAI)   -- Temps atomique international
   ,TAIDiff(TAIDiff)
   ,taidelta  -- TAI - TAI - TAIDiff
   ,taimove   -- TAI - TAIDiff - TAI
   ,taiadd-- TAIDiff - TAIDiff - TAIDiff
   ,taisub-- TAIDiff - TAIDiff - TAIDiff
   ,taimult   -- Rational - TAIDiff - TAIDiff
   ,taipow-- Integer  - TAIDiff - TAIDiff
   ,tainegate -- TAIDiff - TAIDiff
   ,tairecip  -- TAIDiff - TAIDiff
   ,unixEpoch -- TAI
   ,LeapSeconds(LeapSeconds)
   ,emptyLeaps-- LeapSeconds table valid until ISO 1970-01-01
   ,leaps_2002_06_01  -- LeapSeconds table valid until ISO 2002-06-01
   ,UTC(UTC)
   ,tai2utc   -- LeapSeconds - TAI - UTC
   ,utc2tai   -- UTC - TAI
   ,MJD(MJD)  -- Modified Julian Date
   ,utc2mjd   -- UTC - MJD
   ,mjd2utc   -- MJD - UTC
   ,JD(JD)-- Julian Date
   ,mjd2jd-- MJD - JD
   ,jd2mjd-- JD  - MJD
   ,ISO
   ,mjd2iso   -- MJD - ISO
   ,iso2mjd   -- ISO - MJD
 )
 where

 import Prelude
 import List
 import Ratio

Values of TAIDiff contains (fractional) seconds without
a reference point.

 newtype TAIDiff = TAIDiff Rational
 deriving (Eq,Ord,Show,Read)

This belongs almost to the class Num, but multiplication
does not make sense - you would get square seconds. Thus,
we have to define our own functions until
class (UnitRing r, Group a)  = Modul a
enters Haskell.

 taidelta (TAI r1) (TAI r2) = TAIDiff (r1 - r2)
 taimove (TAI r1) (TAIDiff r2) = TAI (r1 + r2)
 taiadd (TAIDiff r1) (TAIDiff r2) = TAIDiff (r1 + r2)
 taisub (TAIDiff r1) (TAIDiff r2) = TAIDiff (r1 - r2)
 taimult r1 (TAIDiff r2) = TAIDiff (r1 * r2)
 taipow i (TAIDiff r) = TAIDiff (r ^^ i)
 tainegate (TAIDiff r) = TAIDiff (- r)
 tairecip (TAIDiff r) = TAIDiff (1/r)

Values of TAI are fixed points on the time axis of the eigentime
of the standardisation organisation in our space-time universe.

 newtype TAI = TAI Rational
 deriving (Eq,Ord,Show,Read)
 untai (TAI r) = r

The first defined TAI value - UNIX(TM) epoch, i.e.
Thursday ISO 1970-01-01T00:00:00

 unixEpoch = TAI 10
   -- == ISO 1970 01 01 0 0 0 emptyLeaps
 libtaiEpoch = 4611686018427387914 -- 2^62 + 10

The leap second table data structure

 data LeapSeconds = LeapSeconds
TAI{- valid until -}
[(TAI, {- when -}
  Bool {- It is additional. -}
)]
  deriving (Eq,Show,Read)

Valid leap second table for all times before unix epoch.

 emptyLeaps = LeapSeconds unixEpoch []

Up to date leap seconds can be found at some official sources:
http://maia.usno.navy.mil/leapsec.html
http://hpiers.obspm.fr/webiers/general/earthor/utc/UTC.html

 leaps_2002_06_01 =
   let
  valid = utc2tai $ mjd2utc $ iso2mjd $ ISO 2002 06 01 23 59 59 lst
  lst@(LeapSeconds _ ls) =
 h 1998 12 31 True
 $ h 1997 06 30 True
 $ h 1995 12 31 True
 $ h 1994 06 30 True
 $ h 1993 06 30 True
 $ h 1992 06 30 True
 $ h 1990 12 31 True
 $ h 1989 12 31 True
 $ h 1987 12 31 True
 $ h 1985 06 30 True
 $ h 1983 06 30 True
 $ h 1982 06 30 True
 $ h 1981 06 30 True
 $ h 1979 12 31 True

Re: [mercury-users] pragma compiled_memo for compile-time tabled evaluation

2003-09-05 Thread Stefan Karrmann
André Platzer (Fri, Sep 05, 2003 at 04:03:42PM +0200):
 Hello Mercury users!
 
 Is there any way to extend tabled evaluation to compile-time? As far as 
 I understand, normal tabled evaluation memorises values computed at 
 run-time. On an invocation with the same arguments, then mercury reuses 
 those values instead of a second computation. This is very cool.
 
 However, I wonder if there is a way to extend this idea to compile-time. 
 So in case of a constant function like
 
%% computes the number pi with a precision of 500 digits.
:- func pi_to_500_digits = string.
:- mode pi_to_500_digits = out is det.
:- pragma memo(pi_to_500_digits/0).
 
 after compilation, the program will compute pi to 500 digits only at the 
 first time this constant is used, but repeat this computation for every 
 program run. An improvement in this situation of constant functions (or 
 at least functions depending upon arguments of a small finite domain) 
 would be to perform the respective computation only once, at 
 compile-time instead of repeatedly at each new program run. The compiler 
 would evaluate the function at compile-time and store its tabled value 
 instead of the machine code for performing the computation.

How could one balance compile-time computation against space
consumption? E.g. (in Haskell - sorry)

pi_s_500_digit = pi_to_500_digits !! 500

The space consumption of the result is small, but the computation is
expensive. This is a good case for compile-time computation. While

enumerate_123456 = [1..123456]

consumes much space and minimal time. To decide automatically about
compile-time computation we may need a pragma that sets a threshold:

:- pragma reductions_per_byte_at_compile_time(10).

Store the value in the library if the compiler needs 10 or more
reductions per byte of the value.

Sincerly,
-- 
Stefan
___
Haskell mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell


Re: Proposal for a new I/O library design

2003-07-29 Thread Stefan Karrmann
Ben Rudiak-Gould (Sun, Jul 27, 2003 at 09:35:41PM -0700): 
  module System.ProposedNewIOModel (...) where
 
 I assume that all I/O occurs in terms of octets. I think that this
 holds
 true of every platform on which Haskell is implemented or is likely to
 be
 implemented.
 
  type Octet = Word8 

If it should be really generall the base type should be Bool.

 File offsets are 64 bits on all platforms. This model never uses
 negative
 offsets, so there's no need for a signed type. (But perhaps it would
 be
 better to use one anyway?) BlockLength should be something appropriate
 to
 the architecture's address space.
 
  type FilePos = Word64
  type BlockLength = Int
 
 type FilePos = Integer 
 type BlockLength = Integer 
 
  data File   -- abstract

I would prefer: 

data ImmutableStore   -- abstract
data MutableStore -- abstract

A note about buffering:
Actually, current UNIX kernels do not support non-blocking descriptors;
they support non-blocking open files. Furthermore, many programs will
break if they encounter non-blocking mode. This means that you must not
[change blocking mode] for a descriptor inherited from another program.
See http://cr.yp.to/lib/io.html.

 A value of type InputStream or OutputStream represents an input or
 output
 stream: that is, an octet source or sink. Two InputStreams or
 OutputStreams compare equal iff reading/writing one also reads/writes
 the
 other.

 (Should I call these ports instead of streams? How about
 OctetSource
 and OctetSink?)

  data InputStream-- abstract
  data OutputStream   -- abstract

Use

data OctetSource-- abstract  (or BitSource, s.a.)
data OctetSink  -- abstract  (or BitSink, s.a.)

for octets (or bits/bools) and

data PacketSource   -- abstract
data PacketSink -- abstract

to send complete packets of data by the latter.

Sincerly,
--
Stefan
___
Haskell mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell


Re: Function composition and currying

2003-07-18 Thread Stefan Karrmann
K. Fritz Ruehr (Wed, Jul 16, 2003 at 11:19:55PM -0700):
  c0 = ($)  -- application

 c1 = (.)  -- good old composition
 
 c2 = (.) . (.)-- my (.) from above
 
 c3 = (.) . (.) . (.)
 
 c4 = (.) . (.) . (.) . (.)
 
 -- etc.
 
 Each of these gives an appropriate generalization allowing the
 composition of a one-argument function with an n-argument one (similar
 to the notations used in the usual definitions for primitive recursive
 function). That is to say, the types are as follows (the middle three
 dots on the second line are an ellipsis, apologies in advance):
 
 cn :: (a - b) - F(t,n,a) - F(t,n,b)
 
 cn  = (.)  .  ...  .  (.)  -- n occurrences of (.)
 
 where the awkward phrase F(t,n,x) expands as follows via some imagined
 macro facility.
 
 F(t,n,x)  ===  t1 - t2 - ... - tn - x
 
 Of course, what we really want to do is to express this as a fold of
 composition over a dynamically generated list of compositions, i.e.:
 
 c n = foldr (.) id (take n (repeat (.)))
 
 But I think giving this a nice general type, where n is a run-time
 argument and the replicated (.)s have distinct but related types,
 is quite difficult.

Such an abstraction would not only be good for functions but also for
tuples.

  t 0 = ()  -- void
  t 1 = t1  -- singleton
  t 2 = (t1,t2) -- tuple
  t 3 = (t1,t2,t3)  -- triple
  t n = (t1,...,tn) -- n-tuple

or even more general

  t * = (t1,t2,...) -- countable infinite tuple

such that

  t n == t[forall k in Natural without Zero . t(n+k) = t 0]

and something like

  curry   :: (t * - a) - c * - a
  uncurry :: (c * - a) - t * - a
  zip :: c [*] - [t *] -- What's a good notation for this?
  unzip   :: [t *] - c [*]

(Maybe only with n instead of * forall n.)

-- 
Stefan Karrmann
___
Haskell mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell


[OT] Re: time since the epoch

2003-02-25 Thread Stefan Karrmann
Peter Thiemann (Mon, Feb 10, 2003 at 04:36:17PM -0800):
  Stefan == Stefan Karrmann [EMAIL PROTECTED] writes:
 
 Stefan Peter Thiemann (Thu, Feb 06, 2003 at 12:40:14PM -0800):
  John's code illustrates TimeDiff's deficiencies perfectly:
  
  There is also a more fundamental problem with the TimeDiff data
  type. While seconds, minutes, hours, and days are clearly specified
  amounts of time, the duration of a month or a year may vary depending
  on the reference point where the time difference is applied.
 
 Stefan What time takes a year - 365 or 366 days? There are leap years!
 Stefan What time takes a month - 28, 29, 30 or 31 days?
 Stefan A week takes 7 days.
 Stefan How long is a day - 86399, 86400 or 86401 seconds and how long is a
 Stefan hour - 3599, 3600 or 3601 seconds? There are leap seconds!
 Stefan A second is the basic amount of time.
 
 Minutes, hours, and days (even weeks) are also well defined in terms
 of seconds. But not months and years.

No! There are leap seconds which let some minute contain exactly 61 or 59
seconds!

Thus, you have a different fixed scales. The elements of each scale
are given by a FIXED number of the first element.:

1. Seconds (SI-unit), kilo seconds, etc.
2. Minute, hours, days, weaks
3. Months, years, decades, centuries, ages, etc.


  My conclusion is that time differences really should be measured in
  seconds and picoseconds. 
 
 Stefan How do you measure 100 attoseconds?
1 attoseconds (1E-18 seconds) is a lot smaller then 1 picosecond.
 
  type TimeDiff = (Integer, Integer)

Should (x,y) :: TimeDiff mean the fractional x/y ?
If you still intend x to be seconds and y to be picoseconds you cannot
represent attoseconds .

 Stefan More general is
 
 Stefan newtype TimeDiff = TimeDiff Rational
 Stefanderiving (Eq, Ord)
 
 I agree, I just was not bold enough to propose this :-)
 However, this seems to be close to the limit of the measurable, and
 I'm wondering how much precision is required in practice.

Here you are right. But if your calculations takes the same precision
adding rationals is cheap.

  Hmm, this is underspecified!
  As another poster said, (pointing out http://cr.yp.to/libtai, but it
  is better to look at http://cr.yp.to/time.html, which has a discussion
  on UTC vs TAI vs UNIX time) the official source of time is TAI, so it
  is best to base a time library
  *on the number of TAI seconds since a reference date*
  (which is btw what the libtai is all about).
  For compatibility with UNIX time, Arthur David Olson's popular time
  library uses an epoch of 1970-01-01 00:00:10 TAI
  [http://cr.yp.to/proto/utctai.html]. 
  So this mostly means that you need to set your system clock correctly:-)
 
 Stefan No, you have to check for leap seconds. There is one in
 Stefan every few years. 
 
 I do not understand this comment. All I am saying is that you should
 set your system clock to the number of seconds since the epoch. Leap
 seconds only come into play when converting to UTC.
 
 -- 
 Peter Thiemann, Prof. Dr.
 Institut für Informatik, Universität Freiburg, Germany
 http://www.informatik.uni-freiburg.de/~thiemann
 ___
 Haskell mailing list
 [EMAIL PROTECTED]
 http://www.haskell.org/mailman/listinfo/haskell

-- 
Stefan Karrmann
___
Haskell mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell


Re: two easy questions

2003-02-23 Thread Stefan Karrmann
Mike T. Machenry (Wed, Feb 19, 2003 at 10:23:45PM -0500):
 Question 1: Is there an easier, more elegant way to write this code?
 
 output a b c d e = println Hello, this is  ++ show a ++  a really hard 
   to write function that  ++ show b ++  would be easier to write with 
   a printf  ++ show c ++ show d ++ show e
You can write a printf-like function in Haskell, s.t.
output = construct-printf.hs

google it, since I do not remember the location of the paper.

 -- ?
 
 Thanks for the help.
 -mike

-- 
Stefan Karrmann
___
Haskell mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell


Re: time since the epoch

2003-02-10 Thread Stefan Karrmann
Peter Thiemann (Thu, Feb 06, 2003 at 12:40:14PM -0800):
 John's code illustrates TimeDiff's deficiencies perfectly:
 
 There is also a more fundamental problem with the TimeDiff data
 type. While seconds, minutes, hours, and days are clearly specified
 amounts of time, the duration of a month or a year may vary depending
 on the reference point where the time difference is applied.

What time takes a year - 365 or 366 days? There are leap years!
What time takes a month - 28, 29, 30 or 31 days?
A week takes 7 days.
How long is a day - 86399, 86400 or 86401 seconds and how long is a
hour - 3599, 3600 or 3601 seconds? There are leap seconds!
A second is the basic amount of time.

 My conclusion is that time differences really should be measured in
 seconds and picoseconds. 

How do you measure 100 attoseconds?

 type TimeDiff = (Integer, Integer)

More general is

newtype TimeDiff = TimeDiff Rational
   deriving (Eq, Ord)

 Hmm, this is underspecified!
 As another poster said, (pointing out http://cr.yp.to/libtai, but it
 is better to look at http://cr.yp.to/time.html, which has a discussion
 on UTC vs TAI vs UNIX time) the official source of time is TAI, so it
 is best to base a time library
 *on the number of TAI seconds since a reference date*
 (which is btw what the libtai is all about).
 For compatibility with UNIX time, Arthur David Olson's popular time
 library uses an epoch of 1970-01-01 00:00:10 TAI
 [http://cr.yp.to/proto/utctai.html]. 
 So this mostly means that you need to set your system clock correctly:-)

No, you have to check for leap seconds. There is one in every few years.

 Hence, a suitable specification for 
 JM toRawTime :: ClockTime - (Integer,Integer) 
 could be number of seconds since reference point, given as a pair
 (full seconds, picoseconds). This function *may* involve a time zone
 calculation for those that do not run their system clock on TAI (or UTC).
 JM fromRawTime :: (Integer,Integer) - ClockTime
 with
   toRawTime . fromRawTime == id
 and
   fromRawTime . toRawTime ~~ id
   (the internal representation of ClockTime may have less precision,
   so the difference would be less than system dependent constant,
   which could also be supplied by the library)
 
 Given these two raw ingredients, everything else can be computed
 from that. In addition, it would be nice to have parsing functions for
 various time and date formats (which is what I ended up writing
 myself for the ISO8601 format).

Cheers,
-- 
Stefan Karrmann
___
Haskell mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell



Re: time since the epoch

2003-02-10 Thread Stefan Karrmann
Peter Thiemann (Fri, Feb 07, 2003 at 10:22:12AM -0800):
  SM == Simon Marlow [EMAIL PROTECTED] writes:
 SM This isn't a problem with the spec, I think.  A TimeDiff of 1 month is
 SM precisely a difference, which, when added to a given ClockTime, produces
 SM a ClockTime which is one month later (with respect to some timezone,
 SM presumably UTC since it isn't specified otherwise).  That is, January
 SM 12th 12:00 UTC becomes February 12th 12:00 UTC, and so on.  Adding one
 SM month to certain ClockTimes is meaningless: eg. adding one month to
 SM January 31st doesn't work.
 
 Unfortunately, with UTC, this goes on to make adding *anything* except
 seconds to certain ClockTimes (namely the instants of leap seconds,
 eg, what happens if you add 1 minute to 23:59:60 ? This is a perfectly
 legal UTC time on a day with a leap second) meaningless. My take would
 be to look at an established standard for expressing time durations
 (eg, ISO8601) and just adhere to that (but not the POSIX standard,
 please!). Personally, I think that it is unacceptable to make
 something like addToClockTime a partial function.

IMHO, you need two different functions to add time. One that add the
absolute time difference (as TAI seconds). Another one add calendar
times and rounds down as needed, e.g.

(timediff calTime1 calTime2) :: TimeDiff (in years, months, etc.)

floorTimeAdd '2000-01-31' (Month 1) == '2000-02-28'
floorTimeAdd '2004-01-31' (Month 1) == '2000-02-29' -- a leap year

Suppose a leap second:
floorTimeAdd '2000-01-31.23:59:60' (Minute 1) == '2000-02-01.00:00:59'


Cheers,
-- 
Stefan Karrmann
___
Haskell mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell



Re: time since the epoch

2003-02-09 Thread Stefan Karrmann
Matthew Donadio (Fri, Feb 07, 2003 at 01:13:30PM -0500):
 Pretty much the whole world runs on UTC.  All of the common time
 distribution systems use UTC.  Technically, GPS doesn't, but the GPS
 signal includes the correction to UTC.  I understand the argument for
 using TAI.  Maybe internally the libray should use TAI, but default to
 giving the user UTC?

Yes, TAI should be the base to add seconds. (It's a total function!)
Two functions should connect it to UTC, e.g.:

taiutc :: UTCleaps - TAItime - (UTCtime, Bool {-isLeap-})
utctai :: UTCleaps - Bool {- isLeap -} - UTCtime - TAItime

where

newtype UTCleaps = UTCleaps ( [ (TAItime,Bool {- Skipped or Additional -}) ],
  TAItime {- valid (at least) until -} )
newtype UTCtime = UTCtime Rational

Note: o It is easy to use (utctai leaps False) and
(\t - first (taiutc leaps t)) as a simple interface.
  o Only, programs that run several month have to update the
leap-seconds table more than once.

On UTCtime we can build ISO, Gregorian, Julian, etc. calendars.


Cheers,
-- 
Stefan Karrmann
___
Haskell mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell



Re: time since the epoch

2003-02-07 Thread Stefan Karrmann
Keith Wansbrough (Thu, Feb 06, 2003 at 05:46:22PM +):
 Stefan Karrmann [EMAIL PROTECTED] writes:
 
  A sound base for a Time implementation should use TAI (temps atomique
  international), c.f. http://cr.yp.to/libtai.html.
 
 I disagree; I think UTC is quite sufficient, and will match the users'
 expectations much better.  (executive summary: UTC is the time on your
 watch (+/- timezone of course), TAI is behind by a few seconds, and
 this difference changes each time there's a new leap second).
 
 However, the reference above is not to TAI, but to a library called
 libtai.  I don't know anything about this; Stefan, maybe you could
 tell us some more?

One TAI second is defined as the duration of 9192631770 periods of the
radiation corresponding to the transition between the two hyperfine
levels of the ground state of the cesium atom (quoted from
http://cr.yp.to/libtai/tai64.html). Therefore, it is easy to add
seconds to a TAI-label. If you have a leap-second table, you can
easily convert TAI into UTC but not visa-versa (afaik), since in UTC
leap-seconds are mapped to the previous second! (You need a leap-flag.)
From UTC to CalenderTime (Gregorian (from 1582) or ISO time) is
straight forward.

Libtai is a public domain implementation of 64-bit TAI-labels, which
are defined from 1E+11 years before 1970 to 1E+11 years after 1970.
Thus this would avoid year 2038 and 2036 bugs of other common time
representations.

References (some may moved into nirwana):
1. http://www.boulder.nist.gov/timefreq/general/glossary3.htm
2. http://www.boulder.nist.gov/timefreq/pubs/bulletin/leapsecond.htm
3. http://sadira.gb.nrao.edu/~rfisher/Ephemerides/times.html
4. http://purl.org/DC/elements/1.1/

Sincerly,
-- 
Stefan Karrmann
___
Haskell mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell



Re: time since the epoch

2003-02-06 Thread Stefan Karrmann
Simon Peyton-Jones (Mon, Feb 03, 2003 at 10:06:40AM -):
 
 | the haskell 98 time library is horribly broken, if you are using ghc,
 | you can deconstruct the time constructor which has an Integer
 containing
 | the number of seconds since epoch... otherwise you can use
 | 
 ...
 | I dont supose this could be considered a typo in the haskell 98
 report?
 | it is an embarasing thing for a language to not be able to do...
 
 Meanwhile, I suspect there's an opportunity for someone (or a small
 group) to suggest a new Time library that really does the business, and
 provide an implementation.  If it's sufficiently persuasive, all the
 implementations will adopt it and it can become a de-facto standard.

A sound base for a Time implementation should use TAI (temps atomique
international), c.f. http://cr.yp.to/libtai.html.

 The implementation is important because Time is a weird enough thing
 that only an expert can implement the spec!  

-- 
Stefan Karrmann
___
Haskell mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell



Re: Text in Haskell: a second proposal

2002-08-15 Thread Stefan Karrmann

Marcin 'Qrczak' Kowalczyk Sat, Aug 10, 2002 at 09:02:30AM +:
 Thu, 8 Aug 2002 23:40:42 -0700, Ashley Yakeley [EMAIL PROTECTED] pisze:
 
  1. Octets.
  2. C char.
  3. Unicode code points.
  4. Unicode code values, useful only for UTF-16, which is seldom used.
  5. What handles handle.

I disagree, more general would be:

1. Word8
2. CChar
3. Char (or CodePoint)
4. Word16 (or skipped or (Word8, Word8))
5. Integer, and a function hmax: Handle - Integer

Choosing Integer for 5 provides compatibilty with old and future systems.
You can have 8 bits for net handles and e.g. 9 bits for files. You can even have
3.32 bits if hmax h returns 10.
Using type 5 as a lowest level a library can provide higher level access with
standard or special encodings.

Sincerly,
-- 
Stefan Karrmann
___
Haskell mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell



Dependent types (Was: Re: BAL paper available)

2001-05-23 Thread Stefan Karrmann

C T McBride schrieb folgendes am Wed, May 16, 2001 at 01:03:25PM +0100:
 On Wed, 16 May 2001, Stefan Karrmann wrote:
  On Tue, May 15, 2001 at 09:14:02PM +0300, Dylan Thurston wrote:
   On Tue, May 15, 2001 at 06:33:41PM +0200, Jerzy Karczmarczuk wrote:
   ... you really need types that
   depend on parameters (in particular, integer parameters).  This is,
   indeed, a problem--currently, you have to do runtime checks.
   
   Full-fledged dependent types à la Cayenne are undecidable, but there
   are weaker variants that are likely to be good enough.
  
  What are the weaker variants? Do you know some references?
  Are they still decidable? That surprises me. If you allow integer
  arithmetic you can do already all computations (Church).
 
 The idea that `dependent types are undecidable' is a popular but
 understandable misconception arising from a particular design decision in
 a particular system---Cayenne.
 
 Dependent types as found in proof systems such as Coq and Lego do have
 decidable typechecking: programs may only use structural recursion, and
 hence all the evaluation which takes place during typechecking is
 guaranteed to terminate. However, in order to support real programming,
 Cayenne allows general recursion: as it makes no distinction between the
 programs which are executed at compile-time and those only executed at
 run-time, undecidability creeps in. Understandably, neither horn of this
 dilemma is particularly attractive to programmers who want to combine
 flexibility at run-time with a genuinely static notion of typechecking. 

With constructor type we can do dimension checking, as shown earlier on this list.
Can't we check in a similiar way an integer paramter? But is this general enough?
You may compute some integer n and then do some calculations in Z/n. How
can this be done? Do you need to do the calculation only with structural recursion?

 (Of course, post-98 Haskell with certain type class options selected has a
 type-level language containing non-terminating programs, making
 typechecking undecidable for exactly the same reason as in Cayenne.)

If possibly non-terminating type analysis creeps into Haskell, why don't we
choose the Cayenne style?
 
 However, there is a middle way: we can distinguish compile-time programs
 from run-time programs and restrict the former to the structurally
 recursive fragment, leaving general recursion available in the latter. 

Is there any (syntactical) proposal somewhere?

-- 
Stefan Karrmann


___
Haskell mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell



Re: BAL paper available

2001-05-15 Thread Stefan Karrmann

On Tue, May 15, 2001 at 09:14:02PM +0300, Dylan Thurston wrote:
 On Tue, May 15, 2001 at 06:33:41PM +0200, Jerzy Karczmarczuk wrote:
  Serge Mechveliani :
   ...
   The matter was always in parametric domains ...
   Whoever tried to program real CA in Haskell, would agree that such a
   problem exists.
 
 Can you be more precise what the problem is?  One problem I see is
 that referred to in Section 3 of the paper: you really need types that
 depend on parameters (in particular, integer parameters).  This is,
 indeed, a problem--currently, you have to do runtime checks.
 
 Full-fledged dependent types à la Cayenne are undecidable, but there
 are weaker variants that are likely to be good enough.

What are the weaker variants? Do you know some references?
Are they still decidable? That surprises me. If you allow integer
arithmetic you can do already all computations (Church).

-- 
Stefan Karrmann

___
Haskell mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell



Re: Proposal: module namespaces.

2001-02-27 Thread Stefan Karrmann

Malcolm Wallace schrieb folgendes am Mon, Feb 26, 2001 at 05:59:30PM +:
 Proposal 2
 --
 but only a guaranteed-to-be-stable, complete, library could be called
 
 Std.Text.Xml
 
 The implication of the Std. namespace is that all such "standard"
 libraries will be distributed with all Haskell systems.  In other
 words, you can rely on a standard library always being there, and
 always having the same interface on all systems.

What's about version changes? How can anybody garantee that a library is stable?
Some functions or instances may become obsolete or even disappear. Other
may be needed in later versions of the library.

Regards,
-- 
Stefan Karrmann

___
Haskell mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell



Re: binary files in haskell

2001-02-06 Thread Stefan Karrmann

Marcin 'Qrczak' Kowalczyk schrieb folgendes am Tue, Feb 06, 2001 at 12:54:29PM +0100:
 On Tue, 6 Feb 2001, Olaf Chitil wrote:
 
  I just see one problem with John's proposal: the type Byte.
 
 type Byte = Word8

I would prefer

type Octet = Word8

to emphasise that the functions really uses 8 bits.

-- 
Stefan Karrmann

___
Haskell mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell



Re: Are anonymous type classes the right model at all? (replying to Re: Are fundeps the right model at all?)

2001-01-03 Thread Stefan Karrmann

A syntax to choose the active instances may be useful, too.

E.g.:

use EccenticOrd, SetCollection in exp

then in exp the instances  EccenticOrd, SetCollection are known (or preferred).
This is similiar to the open syntax in Cayenne.

-- 
Stefan Karrmann

___
Haskell mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell



Re: Haskell Clean

2000-01-18 Thread Stefan Karrmann

Am Fri, Jan 14, 2000 at 02:23:00PM +0800 schrieb Nguyen Phan Dung:
 So what are the important differences between Clean  Haskell?

What are the pros and cons of unique typing with multiple environments
vs. the IO monad?

Thanks,
-- 
Stefan Karrmann.



State - IO Monad

1997-06-13 Thread Stefan Karrmann

Hi,

it used to be a big problem in functional programming languages (FP)
to handle with input, output and state. Irrefutable patterns, unique
types, continuation passing style and IO monad programming solves this
problem.

In Haskell the IO monad has won the competition between these
solutions. But these leads to another problem:

Every function, that does any IO, has a result type of `IO a',
regardless of the data it actually needs from the state.
E.g. a random-list generating function, that needs only the time for
initialisation of the (internal) seed needs `IO [Int]' as result type,
while a function, that deletes a file needs `IO ()' as result type.

So weather the Programmer nor the Compiler knows which data is
modified by such a function. Because of this, it may be quite
difficult to optimise/parallelise any sequence of functions of the IO
monad.

This particular problem is avoided in Clean by using the uniqness type
attribute. By (de)composing `World', the (hidden) state of the world,
into sub-worlds like `FileSystem', `Events' and sub-sub worlds like
`InFile', `Devices' it is clear which part of the outside, persistent
world is modified by a function. 

It is the questions, if such a decomposition of the hidden state of
the world is possible in Haskell. I think of something like:

main :: ST World ()
getFileSystem :: ST World FileSystem
joinFileSystem :: ST FileSystem a - ST World a

writeCh :: Char - ST File ()
readCh :: ST File Char

or

main :: World ()
getFileSystem :: World (FileSystem ())
joinFileSystem :: FileSystem a - World a

writeCh :: Char - File ()
readCh :: File Char

If a sophisticated decompositions of the world are chosen, it should
be easier to optimise functions locally and globally and to exploit
the parallelism of interactive function. But this proposal may need
the annotation of uniqness. 

Another possibility is something like this:

main :: ST World ()
runFileSystem :: ST FileSystem a - ST World a   -- or syncFileSystem
runFile :: ST File a - ST FileSystem a  --syncFile

writeCh :: Char - ST File ()
readCh :: ST File Char

main = do
runFileSystem  $ do { ... }  -- implicit parallelism
runEventSystem $ do { ... } 
...
return ()

or

main :: World ()
runFileSystem :: FileSystem () - World ()
runFile :: File () - FileSystem ()

writeCh :: Char - File ()
readCh :: File Char


Regards,
Stefan