[Haskell-cafe] Re: how would this be done? type classes?existential types?

2006-03-23 Thread Ben Rudiak-Gould

Brian Hulley wrote:

Is there a reason for using  instead of

  [exists a. Resource a=a]

?


Only that = looks like a function arrow,  looks like a tuple. I stole 
this notation from an unpublished paper by SimonPJ et al on adding 
existential quantification to Haskell. I'm not especially attached to it. 
Actually I rather like


forall a | Resource a. a
exists a | Resource a. a

a) A value 'v' of type 'exists a. Resource a=a 'would have to be 
internally represented as something like (dictResource_t, value_t)


Yes.

b) Given such a value, there is no syntactic way to distinguish the pair 
from the value_t stored inside it, unlike the use of 'forall' where the 
syntax for the constructor conveniently represents any dictionaries 
that have been glued onto the value (ie pattern matching against R x 
gives us back the dictionaries R and the plain value x)?


Yes, but that doesn't necessarily mean you can't work out when to construct 
and deconstruct these implicit tuples. That's exactly what the type 
inference process does with implicit type arguments, and implicit type 
returns are dual to that, so the process should be similar.


It is tricky, though. E.g. given (f (g z)) where

   f :: forall a. [a] - Int
   g :: String - (exists b. [b])

in principle you should be able to call g first, getting a type b and a list 
[b], then instantiate f with the type b, then pass the list to it, 
ultimately getting an Int. But I don't know how to design a type inference 
algorithm that will find this typing. If on the other hand


   f :: (exists a. [a]) - Int

then it's easy to do the right thing---which is a little odd since these two 
types for f are otherwise indistinguishable.


Hope I'm not making this more confusing but I'm still trying to get my 
head around all these invisible happenings regarding dictionaries so I 
can visualise what's happening in terms of bytes and pointers in the 
runtime


Once you understand where the types go in System F, the dictionaries are 
easy: they always follow the types around. Any time you have


forall a b c. (C1 a b, C2 b c) = ...

in the source, you have five corresponding parameters/arguments in GHC Core, 
one for each type variable and constraint. These are always passed around as 
a unit (at least prior to optimization). In principle you could box them in 
a 5-tuple. The dictionary values are nothing more or less than proofs that 
the corresponding constraints hold.


-- Ben

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


[Haskell-cafe] Re: how would this be done? type classes? existential types?

2006-03-17 Thread Ben Rudiak-Gould

Matthias Fischmann wrote:

now i want to create a list of a type similar to

  [r1, r2, r3] :: (Resource a) = [a]

but with r1 being pizza, r2 being crude oil, and so on.


The type you actually want here is [exists a. (Resource a)  a], but no 
Haskell implementation supports that.



  data Rs = forall a . (Resource a) = Rs a
  unRs (Rs a) = a
  rsName :: Rs - String
  rsName = resourceName . unRs
  ...

[...]

but what is the type of unRs?


Its type is (Rs - (exists a. (Resource a)  a)), but again no Haskell 
implementation supports that.


-- Ben

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


[Haskell-cafe] Re: how would this be done? type classes? existential types?

2006-03-17 Thread Ben Rudiak-Gould

Matthias Fischmann wrote:

On Thu, Mar 16, 2006 at 12:40:00PM +, Chris Kuklewicz wrote:

(Why isn't it resourceName :: String ?)


when i am trying this, ghc complains that the type of resourceName
doesn't have any occurrance of 'a', and i feel that it must be harder
for the type engine to figure things out if there isn't, so
resourceName is still a mapping from resources to their names.


Yes, if you had

resourceName :: forall a. Resource a = String

then there'd be nothing to prevent the expression (resourceName :: String) 
from evaluating to any resource name in any context.


A trick you can pull is to define

data Proxy a = Proxy

and give resourceName's parameter the type Proxy a instead of a. This makes 
it clear that it's only the type you care about, not the value. The downside 
is that it tends to be less convenient to use, which is presumably why 
standard library functions with this problem (like floatRadix and sizeOf) 
don't use this solution.


-- Ben

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