RE: linker errors

2003-08-05 Thread Simon Peyton-Jones
| The code is hand-written and the maximum tuple-size
| used is 4. It works fine in Hugs. It uses the Parsec
| library (not the version in GHC's text package, but
| from a local copy. The ParsecPrim.hs was replaced by
| the version from Parsec's web-site -- it works as I
| expected, but not the one distributed with GHC or
| Hugs).

Well that is mysterious.  Can you send the offending source code (plus
the modules it imports, and a Makefile)?  Preferably with as few imports
as possible...

Simon


___
Glasgow-haskell-users mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users


RE: Polymorphic kinds

2003-08-05 Thread Simon Peyton-Jones
The real question is:
why does GHC distinguish kind * from kind #?

For example,  Int   has kind *
Int# has kind #

The main reason is this: a polymorphic function assumes that values of
type 'a' are represented by a pointer.  For example:
const :: a - b - a
const assumes that its arguments are represented by pointers.  The
machine instructions simply would not work if it was passed (say) two
double-precision floats, of type Double#.

To avoid this bad thing happening, GHC imposes the following rule
(described in detail in Unboxed values as first class citizens
http://research.microsoft.com/~simonpj/Papers/unboxed-values.ps.Z)

A polymorphic type variable (such as 'a' and 'b' in the type of
const) can
only be instantiated by a boxed type (of kind *)

Value whose type is of kind * are always represented by a pointer.
Value whose type is of kind # are represented in a type-dependent way.


In your particular case, consider '='.  It is required to transport
the value returned by its left argument to the function that is its
right argument.  The machine instructions reqd to do that differ if the
value so transported is an Int#.

[One of the big advantages of .NET is that its generic type system
*does* allow polymorphic type variables to be instantiated with unboxed
types, using run-time code generation to fluff up copies of the
function code instantiated with the representation type.]


[An Int# is the same size as a pointer, yes, but its GC behaviour is
different.]


Now, do-notation expands to the overloaded '=' stuff, so you are
stuck.

It would be possible, I guess, to change the way in which do-notation
expanded, so that in the special case of the IO monad unboxed LHSs were
allowed.  That might allow you to use do-notation, but it seems a bit ad
hoc.

Simon
   
| -Original Message-
| From: [EMAIL PROTECTED]
[mailto:[EMAIL PROTECTED]
| On Behalf Of Sebastien Carlier
| Sent: 04 August 2003 16:09
| To: [EMAIL PROTECTED]
| Subject: Polymorphic kinds
| 
| 
| Hello,
| 
| I am experimenting with GHC to write low level code (e.g., device
| drivers, interrupt handlers).  The ultimate goal is to write a
| prototype operating system in Haskell, using the GHC RTS as a kind of
| microkernel (this appears to be relatively easy by removing all the
| dependencies on an operating system, and providing a block allocator
| and interval timers).
| 
| I have added the necessary primitive operations to generate privileged
| instructions for IA32 to GHC, and it seems to work fine, good quality
| assembly code is generated.
| 
| Now, I would like to make use of do-notation to write cleaner code
| (threading a State# RealWorld through computations is quite ugly).
| I want to avoid allocating memory in parts of the code, so I would
| like to be able to have monadic computations which return unboxed
| values.  Sadly, GHC currently does not appear to allow that.
| 
| The following example illustrates the problem:
| 
|  {-# OPTIONS -fglasgow-exts #-}
| 
|  import GHC.Prim
| 
|  x :: IO Int#
|  x =
|  return 1#
| 
| GHC (HEAD from 2003-08-01) reports:
| 
| T.lhs:5:
| Kind error: Expecting a lifted type, but `Int#' is unlifted
| When checking kinds in `IO Int#'
| In the type: IO Int#
| While checking the type signature for `x'
| 
| T.lhs:7:
| Couldn't match `*' against `#'
| When matching types `a' and `Int#'
| Expected type: a
| Inferred type: Int#
| In the first argument of `return', namely `1#'
| 
| After looking into the problem for a while, I realized that GHC does
| not have polymorphic kinds - after checking a bunch of definitions, it
| zonks all kind variables to (Type *) and all boxity variables to *.
| So IO has kind (Type * - Type *), and cannot be applied to an unboxed
| value of kind (Type #).
| 
| GHC has had explicit kind annotations for a while:
| http://www.haskell.org/pipermail/haskell/2002-February/008906.html
| So I ought to be able define an IO# type for computations that return
| unboxed values.
| (By the way, is there already an unboxed unit value and type?)
| 
| Strangely, GHC did not recognizes # as the kind of unlifted types, so
| I added that to the compiler, and hoped that things would work out.
| Well, almost.
| 
|  {-# OPTIONS -fglasgow-exts #-}
| 
|  import GHC.Prim
| 
|  newtype IO# (a :: # ) = IO# (State# RealWorld - (# State#
RealWorld, a #))
| 
|  x :: IO# Int#
|  x = IO# (\ s - (# s, 1# #))
| 
| GHC reports:
| 
| T.lhs:8:
| Illegal unlifted type argument: Int#
| In the type: IO# Int#
| While checking the type signature for `x'
| 
| The example is accepted if newtype is replaced by type (and by
| removing uses of the IO# value constructor), so I can proceed with my
| experiment by not using do-notation (defining return#, then#, etc
| appears to work fine).
| 
| Not being able to use do-notation is slightly inconvenient; is there a
| reason why newtypes cannot be applied to 

bug(?) in unblockThread?

2003-08-05 Thread Hal Daume
I've implemented timeouts as described in:

 
http://www.haskell.org/pipermail/glasgow-haskell-users/2001-April/001816
.html

My implementation follows:

timeout secs onTimeout action = do
  parent - myThreadId
  i  - newUnique
  block $ do
timeoutT - forkIO (timeoutThread secs parent i)
catchDyn
  (unblock $ do
 result - action
 killThread timeoutT
 return result)
  (\exception -
 case exception of
   TimeOut u | u == i - unblock onTimeout
   _ - do killThread timeoutT; throwDyn exception)
  where
timeoutThread secs parent i = do
  threadDelay (secs * 2000);
  throwTo parent (DynException (toDyn (TimeOut i)))

which is basically just a rewrite of the amove url (except for the
multiplier in the call the threadDelay, which needs to be a lot smaller
than they had, for some reason).

However, I cannot seem to run this:

*Main let loop :: IO () = threadDelay 100  loop  return ()
*Main timeout 1 (return ()) loop
interactive: internal error: unblockThread (I/O): TSO not found
Please report this as a bug to [EMAIL PROTECTED],
or http://www.sourceforge.net/projects/ghc/

Process ghci exited abnormally with code 254


I put the threadDelay in the loop to prevent a stack overflow.  This is
on Win32, GHC 6.0.  Any thoughts?  The same thing happens when this is
compiled, so it's not a ghci thing.

The same code seems to work fine on Linux and Solaris.  Is this a win32
thing?  If it is, is there another way I can get the same effect?



--
 Hal Daume III   | [EMAIL PROTECTED]
 Arrest this man, he talks in maths.   | www.isi.edu/~hdaume
___
Glasgow-haskell-users mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users


Re: The madness of implicit parameters: cured?

2003-08-05 Thread Ben Rudiak-Gould
On Mon, 4 Aug 2003, Ashley Yakeley wrote:

 At 2003-08-04 20:00, Ben Rudiak-Gould wrote:
 
 This is a different lambda calculus, with a different beta rule. You can
 see the same effect in the type inference rules for implicit parameters:
 If f has type Int - String and ?x has type (?x :: Int) = Int, then f ?x
 has type (?x :: Int) = String, i.e. the implicit ?x parameter is lifted
 out of the RHS to become a parameter of the whole application node. This
 rule is what makes implicit parameters implicit.
 
 Ah. Actually I think the beta rule is unchanged with Haskell's implicit 
 parameters. Consider:
 
   x :: (?x :: Int) = Int
   f :: Int - String
   f :: ((?x :: Int) = Int) - ((?x :: Int) = String) -- specialisation
   f x :: (?x :: Int) = String -- apply beta rule

I think it amounts to the same thing. This is a nice way of looking at it,
though. Either way, the effect is that implicit parameters don't
disappear into function applications unless the function has been
explicitly typed to take them; instead they grow to encompass larger and
larger portions of the containing function, until eventually they become
parameters of the whole function. Result: you don't have to put them there
by hand.

 So is this valid or not?
 
   b :: (?x :: Int) = Int
   b = [EMAIL PROTECTED] - @x
 
   f :: ((?x :: Int) = Int) - (Int,Int)
   f = \a - ((a,[EMAIL PROTECTED] - @x) [EMAIL PROTECTED] = 2})
 
   f b :: (Int,Int)
   f b = ((b,[EMAIL PROTECTED] - @x) [EMAIL PROTECTED] = 2})
= (([EMAIL PROTECTED] - @x,[EMAIL PROTECTED] - @x) [EMAIL PROTECTED] = 2})

Yes, it is. This illustrates what you pointed out earlier, that the
program's semantics can be changed by adding explicit type signatures
which include implicitly-parameterized parameters.

 If it is valid, then this must be a valid reduction:
 
   ((\a - ((a,[EMAIL PROTECTED] - @x) [EMAIL PROTECTED] = 2})) ([EMAIL PROTECTED] 
 - @x),[EMAIL PROTECTED] - @x) [EMAIL PROTECTED] = 1}
   (([EMAIL PROTECTED] - @x,[EMAIL PROTECTED] - @x) [EMAIL PROTECTED] = 2},[EMAIL 
 PROTECTED] - @x) [EMAIL PROTECTED] = 1}

Not unless you give an explicit type signature, no. Without it the
compiler will infer a different type for f which does not have any
arguments with implicit parameters, because inferred types never do (see
section 2.1 in the original paper). Without this assumption the compiler
couldn't infer a principal type. (Specialization doesn't help here,
because the set of valid specializations depends on f's internals, and
can't be captured by a principal type.)


-- Ben

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


Solution to the monomorphism restriction/implicit parameter problem

2003-08-05 Thread Ben Rudiak-Gould
I just figured out why the monomorphism restriction interacts so weirdly
with implicit parameters, and how to fix it.

We all know that when the monomorphism restriction is turned on, the
following doesn't work:

let f = () in (f 1 2, f 'a' 'b')

On the other hand, the following does work:

let f = () in (f 'a' 'b', f 'a' 'b')

Why does it work? The answer to this is non-trivial: the compiler must
inspect every use of f in the body of the let statement and try to
statically deduce what dictionary will be passed in each case. If the
deduction succeeds in all cases and the dictionary is the same in all
cases, then the compiler can safely pre-apply that dictionary, reducing f
to a monotype, without changing the semantics of the program. Otherwise,
it can't safely do so, and must abort with an error message.

In short, a let value binding of an expression with type-class constraints
is valid precisely if the compiler can reduce it to a monotype without
changing the semantics of the program.

Exactly the same rule should apply to implicit parameters. In the case of
implicit parameters, safety is ensured if in every use of the bound
variable, its implicit parameter refers to the same explicit binding of
that parameter. For example, the expression

let g = ?x in (g,g)

should be accepted provided there is an enclosing binding of ?x, because
in both uses of g the implicit parameter ?x refers to that same binding.
On the other hand, an expression like

let g = ?x in (g, let ?x = 1 in g)

must be rejected, since it necessarily involves two calls to g.

A much more important example is this:

let ?x = 1 in (let g = ?x in (let ?x = 2 in g))

Here g is used just once, so it can be reduced safely. The value that
should be used for the reduction is the value that is in scope where g is
used (that is, 2), because that is the only way to preserve the semantics
of the program.

For some reason, the current implementations use ?x = 1 for the early
reduction, even though this alters the semantics of the program. In fact,
?x = 1 is not even in scope at the early reduction point, since by the
axiomatic semantics in the Lewis et al. paper,

let ?x = 1 in (let g = ?x in (let ?x = 2 in g))

is equivalent to

let g = ?x in (let ?x = 1 in (let ?x = 2 in g))

(see section 3.1, bottom left corner of the page).

All implementations should be changed so that they do the right thing.

There are some complications which I'll discuss in a followup message.


-- Ben

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


Re: The madness of implicit parameters: cured?

2003-08-05 Thread Ashley Yakeley
At 2003-08-04 18:19, Ben Rudiak-Gould wrote:

 ((\a - ((a,[EMAIL PROTECTED] - @x) [EMAIL PROTECTED] = 2})) ([EMAIL PROTECTED] - 
 @x),[EMAIL PROTECTED] - @x) [EMAIL PROTECTED] = 1}
 ^^^
 (([EMAIL PROTECTED] - @x,[EMAIL PROTECTED] - @x) [EMAIL PROTECTED] = 2},[EMAIL 
 PROTECTED] - @x) [EMAIL PROTECTED] = 1}

This reduction is incorrect.

It's a simple beta-reduction, it must be correct.

b :: (?x :: Int) = Int
b = [EMAIL PROTECTED] - @x

f :: ((?x :: Int) = Int) - (Int,Int)
f = \a - ((a,[EMAIL PROTECTED] - @x) [EMAIL PROTECTED] = 2})

f b :: (Int,Int)
f b = ((b,[EMAIL PROTECTED] - @x) [EMAIL PROTECTED] = 2})


-- 
Ashley Yakeley, Seattle WA

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


Re: *safe* coerce: four methods compared

2003-08-05 Thread oleg

This message illustrates how safe casting with multiple universes can
be extended to new user-defined, polymorphic datatypes. We show a
_portable_ mapping of polymorphic types to integers. Different
instances of a polymorphic type map to different integers. Phantom
types can be either disregarded or accounted for -- as the user
wishes. Furthermore, if two different applications running on two
different machines agree on the same type heap, then they agree on the
type encoding. An application can use multiple typeheaps at the same
time. It is easy therefore to dedicate one particular typeheap for
portable encoding of types across several computers.

Incidentally, our encoding of types may take into account _values_ of
some of the components of a polymorphic type. For example, given a
value of a type 'Foo Int a', the encoding may use the _value_ of the
first component and the _type_ of the second component. When we do the
cast, we can check not only for the desired type but also for the
desired values. We can thus approach dependent types.

This message hopefully replies to Ralf Laemmel's comment:
] You should make very clear that there is
] not just a single safeCoerce, but the TI/init_typeseq argument has to
] be constructed and supplied by the programmer in a way that (s)he
] decides what array of types can be handled.  So if you wanted to use
] your approach to scrap boilerplate [1], say deal with many datatypes,
] this becomes quite a burden.  Think of actually building initial type
] sequences. Think of how combinators need to be parameterised to take
] type sequences.

with which I agree. Below I try to make it very implicit what depends
on TI/init_typeseq and what doesn't, and how much work is involved in
adding new datatypes and extending type heaps. I don't know if the
proposed approach is better than the others in many
circumstances. It's certainly different.

Ralf Laemmel also wrote:
] Software-engineering-wise your approach suffers from an important
] weakness: a closed world assumption.  The programmer has to maintain
] your TI and pass it on in all kinds of contexts for the array of
] types to be handled.

I thought it is a feature. I thought a programmer can import some type
heap, partially apply the needed function to it, and re-export the
latter. The example below demonstrates what is involved when a new
datatype is added. It seems not that much. 


] I didn't need undecidable not even overlapping instances.

I don't actually need overlapping-instances extensions. An earlier
message on the subject of MRefs used similar type heaps without any
need for -fallow-overlapping-instances. However I had to use numeral
types such as Succ (Succ ... Zero) rather than Int for type
indices. The current approach looks more elegant. Besides, you seem to
in favor of giving overlapping instances more acceptance, support and
legitimacy.

] Is it obvious to see that fetching stuff from the type sequences would
] be indeed efficient for long PLists?

The sequence of 'cdr' operations needed for fetching stuff is known
statically. A compiler might therefore do something intelligent.


This whole message is self-contained, and can be loaded as it is in
GHCi, given the flags
  -fglasgow-exts -fallow-undecidable-instances -fallow-overlapping-instances

We start with the boilerplate, which has changed a little (for
example, the class PLists now has a member function pllen).

 data Nil t r  = Nil
 data Cons t r = Cons t r

 class PList ntype vtype cdrtype where
 cdr::   ntype vtype cdrtype - cdrtype
 empty:: ntype vtype cdrtype - Bool
 value:: ntype vtype cdrtype - vtype
 pllen:: ntype vtype cdrtype - Int
   
 instance PList Nil vtype cdrtype where
 empty = const True
 pllen = const 0
   
 instance (PList n v r) = PList Cons v' (n v r) where
  empty = const False
  value (Cons v r) = v
  cdr   (Cons v r) = r
  pllen (Cons v r) = 1 + pllen r
 
 class TypeSeq t s where
 type_index:: t - s - Int
 fetch:: t - s - t
 alter:: t - s - s
   
 instance (PList Cons t r) = TypeSeq t (Cons t r) where
 type_index _ _ = 0
 fetch _ (Cons v _) = v
 alter newv (Cons v r)  = Cons newv r

 instance (PList Cons t' r', TypeSeq t r') = TypeSeq t (Cons t' r') where
 type_index v s = 1 + (type_index v $ cdr s)
 fetch v s = fetch v $ cdr s
 alter newv (Cons v' r') = Cons v' $ alter newv r'

The initial typesequence:

 init_typeseq = Cons (undefined::Char) $
Cons (undefined::Int) $
  Cons (undefined::Bool) $
  Cons (undefined::String) $
  (Nil::Nil () ())

and its type. See the previous message for more discussion of the
latter.

 type TI 
   = (Cons
 Char
 (Cons Int (Cons Bool (Cons String (Nil () ())

Because we will be dealing with existential types, we need to extend
the compile-time indexing into run-time:

 class (TypeSeq t u) = TypeRep t u where
 tr_index:: t - u - Int
 tr_index = 

Re: literate scripts.

2003-08-05 Thread Malcolm Wallace
Immanuel Litzroth [EMAIL PROTECTED] writes:

 I have a small question relating to literate haskell programs that
 use the \begin{code} \end{code} style. Am I correct to assume that 
 \end{code} inside a string should be recognized as being inside a
 string. The report seems to say this, but the unlit that is
 distributed with ghc doesn't grok this. Has anyone written an Unlit
 module in Haskell?

I have attached the Unlit.hs module from the nhc98 compiler, based
on the original specification in the the Haskell 1.2 Report.  Use the
exported function
unlit :: String - String - String
whose first argument is the filename (for error messages), the second
argument is the file content, and whose result is the un-literated
file.

Regards,
Malcolm
module Unlit(unlit) where

-- Part of the following code is from
-- Report on the Programming Language Haskell,
--   version 1.2, appendix C.

import Char

data Classified = Program String | Blank | Comment
| Include Int String | Pre String

classify :: [String] - [Classified]
classify []= []
classify (('\\':x):xs) | x == begin{code} = Blank : allProg xs
   where allProg [] = []  -- Should give an error message,
  -- but I have no good position information.
 allProg (('\\':x):xs) |  x == end{code} = Blank : classify xs
 allProg (x:xs) = Program x:allProg xs
classify (('':x):xs)  = Program (' ':x) : classify xs
classify (('#':x):xs)  = (case words x of
(line:file:_) | all isDigit line
   - Include (read line) file
_  - Pre x
 ) : classify xs
classify (x:xs) | all isSpace x = Blank:classify xs
classify (x:xs) = Comment:classify xs

unclassify :: Classified - String
unclassify (Program s) = s
unclassify (Pre s) = '#':s
unclassify (Include i f) = '#':' ':show i ++ ' ':f
unclassify Blank   = 
unclassify Comment = 

unlit :: String - String - String
unlit file lhs = (unlines
 . map unclassify
 . adjecent file (0::Int) Blank
 . classify) (inlines lhs)

adjecent :: String - Int - Classified - [Classified] - [Classified]
adjecent file 0 _ (x  :xs) = x : adjecent file 1 x xs -- force 
evaluation of line number
adjecent file n y@(Program _) ([EMAIL PROTECTED]  :xs) = error (message file n 
program comment)
adjecent file n y@(Program _) (x@(Include i f):xs) = x: adjecent fi y xs
adjecent file n y@(Program _) (x@(Pre _)  :xs) = x: adjecent file (n+1) y xs
adjecent file n [EMAIL PROTECTED] (x@(Program _)  :xs) = error (message file n 
comment program)
adjecent file n [EMAIL PROTECTED] (x@(Include i f):xs) = x: adjecent fi y 
xs
adjecent file n [EMAIL PROTECTED] (x@(Pre _)  :xs) = x: adjecent file (n+1) y 
xs
adjecent file n [EMAIL PROTECTED]   (x@(Include i f):xs) = x: adjecent fi 
y xs
adjecent file n [EMAIL PROTECTED]   (x@(Pre _)  :xs) = x: adjecent file (n+1) 
y xs
adjecent file n _ ([EMAIL PROTECTED] :xs) = x: adjecent file (n+1) 
x xs
adjecent file n _ []= []

message \\ n p c = Line ++show n++: ++p++  line before ++c++ line.\n
message [] n p c = Line ++show n++: ++p++  line before ++c++ line.\n
message file   n p c = In file  ++ file ++  at line ++show n++: ++p++  line 
before ++c++ line.\n


-- Re-implementation of 'lines', for better efficiency (but decreased laziness).
-- Also, importantly, accepts non-standard DOS and Mac line ending characters.
inlines s = lines' s id
  where
  lines' [] acc = [acc []]
  lines' ('\^M':'\n':s) acc = acc [] : lines' s id  -- DOS
  lines' ('\^M':s)  acc = acc [] : lines' s id  -- MacOS
  lines' ('\n':s)   acc = acc [] : lines' s id  -- Unix
  lines' (c:s)  acc = lines' s (acc . (c:))



RE: Solution to the monomorphism restriction/implicit parameter problem

2003-08-05 Thread Simon Peyton-Jones
| I just figured out why the monomorphism restriction interacts so
weirdly
| with implicit parameters, and how to fix it.

I'm afraid that I have not read all of the recent exciting flood of
messages carefully, but I do remember that the interaction of the
monomorphism restriction with implicit parameters was the subject of a
long debate some time ago.   Indeed, it leads to strange things, as you
have found.  Below I reproduce a long comment from TcSimplify.lhs (one
of GHC's modules) that describes the problem and GHC's solution.  It
explicitly points out that the currently-adopted solution means that
inlining (beta reduction) is not always valid.  This is undoubtedly a
bad thing.  The comment would be better enshrined in GHC's
documentation.

You say that All implementations should be changed so that they do the
right thing.  If only we knew what the Right Thing is!

I believe that your suggestion is 
  * adopt solution (C) in the list below (always generalise implicit
parameters)
  * but reject any program for which that would cause the implicit
function to be called more than once

Maybe that's a good plan, but if so it'd be better to apply it to all
overloaded bindings.  That is: abandon the monomorphism restriction
altogether; instead always generalise every binding (whether function or
non-function binding) but warn or reject the program if it seems that
the implicit function might be called more than once.

Simon

Comments from TcSimplify

Question 3: monomorphism

There's a nasty corner case when the monomorphism restriction bites:

z = (x::Int) + ?y

The argument above suggests that we *must* generalise
over the ?y parameter, to get
z :: (?y::Int) = Int,
but the monomorphism restriction says that we *must not*, giving
z :: Int.
Why does the momomorphism restriction say this?  Because if you have

let z = x + ?y in z+z

you might not expect the addition to be done twice --- but it will if
we follow the argument of Question 2 and generalise over ?y.



Possible choices

(A) Always generalise over implicit parameters
Bindings that fall under the monomorphism restriction can't
be generalised

Consequences:
* Inlining remains valid
* No unexpected loss of sharing
* But simple bindings like
z = ?y + 1
  will be rejected, unless you add an explicit type signature
  (to avoid the monomorphism restriction)
z :: (?y::Int) = Int
z = ?y + 1
  This seems unacceptable

(B) Monomorphism restriction wins
Bindings that fall under the monomorphism restriction can't
be generalised
Always generalise over implicit parameters *except* for bindings
that fall under the monomorphism restriction

Consequences
* Inlining isn't valid in general
* No unexpected loss of sharing
* Simple bindings like
z = ?y + 1
  accepted (get value of ?y from binding site)

(C) Always generalise over implicit parameters
Bindings that fall under the monomorphism restriction can't
be generalised, EXCEPT for implicit parameters
Consequences
* Inlining remains valid
* Unexpected loss of sharing (from the extra generalisation)
* Simple bindings like
z = ?y + 1
  accepted (get value of ?y from occurrence sites)


Discussion
~~
None of these choices seems very satisfactory.  But at least we should
decide which we want to do.

It's really not clear what is the Right Thing To Do.  If you see

z = (x::Int) + ?y

would you expect the value of ?y to be got from the *occurrence sites*
of 'z', or from the valuue of ?y at the *definition* of 'z'?  In the
case of function definitions, the answer is clearly the former, but
less so in the case of non-fucntion definitions.   On the other hand,
if we say that we get the value of ?y from the definition site of 'z',
then inlining 'z' might change the semantics of the program.

Choice (C) really says the monomorphism restriction doesn't apply
to implicit parameters.  Which is fine, but remember that every
innocent binding 'x = ...' that mentions an implicit parameter in
the RHS becomes a *function* of that parameter, called at each
use of 'x'.  Now, the chances are that there are no intervening 'with'
clauses that bind ?y, so a decent compiler should common up all
those function calls.  So I think I strongly favour (C).  Indeed,
one could make a similar argument for abolishing the monomorphism
restriction altogether.

BOTTOM LINE: we choose (B) at present.  See tcSimplifyRestricted



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


literate scripts.

2003-08-05 Thread Immanuel Litzroth
I have a small question relating to literate haskell programs that
use the \begin{code} \end{code} style. Am I correct to assume that 
\end{code} inside a string should be recognized as being inside a
string. The report seems to say this, but the unlit that is
distributed with ghc doesn't grok this. Has anyone written an Unlit
module in Haskell?
Immanuel

***
It makes me uncomfortable to see
An English spinster of the middle class
Describe the amorous effects of `brass',
Reveal so frankly and with such sobriety
The economic basis of society.
W.H. Auden

--
Immanuel Litzroth
Software Development Engineer
Enfocus Software
Kleindokkaai 3-5
B-9000 Gent
Belgium
Voice: +32 9 269 23 90
Fax : +32 9 269 16 91
Email: [EMAIL PROTECTED]
web : www.enfocus.be
***

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


Re: The madness of implicit parameters: cured?

2003-08-05 Thread Ben Rudiak-Gould
On Mon, 4 Aug 2003, Ashley Yakeley wrote:

 At 2003-08-04 22:33, Ben Rudiak-Gould wrote:
 
 This illustrates what you pointed out earlier, that the
 program's semantics can be changed by adding explicit type signatures
 which include implicitly-parameterized parameters.
 
 But wasn't avoiding this a design goal of your proposal?

Yes, and you convinced me that I had to give up on this goal. I'm attached
to my ideas, but only as long as they're right.


  If it is valid, then this must be a valid reduction:
  
((\a - ((a,[EMAIL PROTECTED] - @x) [EMAIL PROTECTED] = 2})) ([EMAIL 
  PROTECTED] - @x),[EMAIL PROTECTED] - @x) [EMAIL PROTECTED] = 1}
(([EMAIL PROTECTED] - @x,[EMAIL PROTECTED] - @x) [EMAIL PROTECTED] = 
  2},[EMAIL PROTECTED] - @x) [EMAIL PROTECTED] = 1}
 
 Not unless you give an explicit type signature, no.
 
 So effectively your proposal is the same as the existing implicit 
 parameter mechanism, except that the compiler is a bit stricter in 
 certain cases where the types are ambiguous?

Yes, it's effectively the same; that was the point. I'm not trying to
create a new language extension, but an improved conceptual foundation for
the existing extension. It's fine if I don't end up with quite the design
I expected, as long as it coheres. The important thing here is the *idea*
of treating implicit parameters as a special kind of named parameter,
rather than via a problematic analogy with Lisp dynamic typing. Everything
else falls naturally (and, I hope, inevitably) out of that idea.

This idea has been very successful so far. For one thing, I just found the
solution to the monomorphism restriction problem that people have been
struggling with for as long as implicit parameters have existed. The
reason I found that answer is that my new treatment changes the design
space in such a way that the solution falls out naturally with a little
coaxing. More than anything else, this makes me think that I've hit on the
right approach to implicit parameters.


-- Ben

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


RE: Text I/O library proposal, first draft

2003-08-05 Thread Hal Daume
this is true; however, it is likely that it would be much faster for me
to read in word8s and parse them to Ints myself than to read in Chars
(using the old libraries) and parse those to ints (I've done some
experiments and the overhead for reading haskell Chars is very
non-negligible).  i'd like to take advantage of this new infrastructure,
if possible...

 --
 Hal Daume III   | [EMAIL PROTECTED]
 Arrest this man, he talks in maths.   | www.isi.edu/~hdaume


 -Original Message-
 From: [EMAIL PROTECTED] 
 [mailto:[EMAIL PROTECTED] On Behalf Of John Meacham
 Sent: Thursday, July 31, 2003 4:36 PM
 To: [EMAIL PROTECTED]; [EMAIL PROTECTED]
 Subject: Re: Text I/O library proposal, first draft
 
 
 presumably if you are doing random access on the file, it is 
 in a known
 nonarbitrary text encoding (like utf8). in which case you can
 read/access the file with the binary routines and just use the
 appropriate text conversions to get data out. 
 John
 
 On Thu, Jul 31, 2003 at 03:55:44PM -0700, Hal Daume wrote:
  Hi Ben,
  
   Bad things:
   
 * There's no way to implement fgetpos/fsetpos type 
 functionality,
   because coders don't expose their internal state. (In 
 fact, there
   would need to be a way to explicitly copy the state, 
 since it may
   well include IORefs, Ptrs, etc.) Is this a serious problem?
  
  Yes!  This is an enormously serious problem.  At least for me.
  
  It's not a problem for writing files, but I really really 
 really need
  this functionality when reading files.  Reason: I'm often 
 tooling around
  in very large (1gb or greater) files which happen to be 
 sorted on some
  sort of index and I need to do binary search in them.  To 
 load all the
  file into Haskell or to do linear search is impossible.
  
  Other than that, I rather like the design.
  
   - Hal
  -- 
  Haskell mailing list
  [EMAIL PROTECTED]
  http://www.haskell.org/mailman/listinfo/haskell
  
 
 -- 
 --
 -
 John Meacham - California Institute of Technology, Alum. - 
 [EMAIL PROTECTED]
 --
 -
 ___
 Libraries mailing list
 [EMAIL PROTECTED]
 http://www.haskell.org/mailman/listinfo/libraries
 
___
Haskell mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell


Re: Another typing question

2003-08-05 Thread Nick Name
On Tue, 5 Aug 2003 12:23:06 +0200
Konrad Hinsen [EMAIL PROTECTED] wrote:

 3
 
  Is there any way to parametrize a type by a value, rather than
  another type? What I would like to do is to define list of length 3
  and list of length 4 as separate parametrization of the same type,
  such that I could write functions that accept lists (under my new
  typename) of any length as long as parameters have the same length.
  The goal is to remove the need for runtime checks all over the code.

This is called dependent types and is not a feature of haskell (nor of
any language that I know); there was cayenne (try a google search) but
I don't believe it is still mantained.

BTW, why is there no general interest for such a thing as dependent
types?

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


Re: Another typing question

2003-08-05 Thread Alastair Reid

  A better solution might be:
  data EmptyList element = EmptyList
  data TrueList list element = TrueList element (list element)
  A list of four Ints for example would be represented by a value of type
  TrueList (TrueList (TrueList (TrueList EmptyList))) Int.

 Isn't that just the Haskell list type by another name?

I think it's quite different.

A Haskell list looks like this:

   1 : 2 : 3 : 4 : []::   [Int]

Note that the type gives no indication of the length of the list.

Wolfgang's lists look like this (I'm adding a 'T_' prefix to the names of the 
type constructors to remove some ambiguity)

  1 `TrueList` 2 `TrueList` 3 `TrueList` 4 `TrueList` EmptyList
  ::
  T_TrueList (T_TrueList (T_TrueList (T_TrueList T_EmptyList))) Int

Note that you can determine the length of the list from the _type_ by counting 
the occurences of T_TrueList in the type.

You can see a fully worked use of this approach in Mark Jones' paper about 
typechecking Java bytecodes by translating them into a Haskell program using 
this kind of encoding.  (I'm not sure if Mark would characterise the paper 
this way but it's what I remember him doing...)

http://www.cse.ogi.edu/~mpj/pubs/funJava.html

--
Alastair Reid

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


Re: Another typing question

2003-08-05 Thread oleg

 Is there any way to parametrize a type by a value, rather than another
 type?

I believe the following web page answers your question:

http://pobox.com/~oleg/ftp/Haskell/number-parameterized-types.html 

It uses parameterization by decimal numbers -- which seem more
natural to read.

 It would be interesting to know if/how you could, e.g., define a
 concatenation function with a type like

Yes, you can -- and the page referenced above does that.
___
Haskell-Cafe mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: Another typing question

2003-08-05 Thread Nick Name
On Tue, 5 Aug 2003 15:23:09 +0200
Wolfgang Jeltsch [EMAIL PROTECTED] wrote:

 
  You could define different types for different natural numbers:
  data Zero = Zero
  data Succ number = Succ number

This resembles

http://www.brics.dk/RS/01/10/

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