Re: [Haskell-cafe] Re: Optimization problem

2006-09-28 Thread Ross Paterson
On Tue, Sep 19, 2006 at 01:52:02PM +0100, Conor McBride wrote:
 [EMAIL PROTECTED] wrote:
 Btw, why are there no irrefutable patterns for GADTs?
 
 Just imagine
 
  data Eq a b where Refl :: Eq a a
 
  coerce :: Eq a b - a - b
  coerce ~Refl a = a
 
 coerce undefined True :: String
 
 Bang you're dead. Or rather... Twiddle you're dead.

Does anything go wrong with irrefutable patterns for existential types?

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


RE: [Haskell-cafe] Re: Optimization problem

2006-09-28 Thread Simon Peyton-Jones
| Does anything go wrong with irrefutable patterns for existential
types?

Try giving the translation into System F.

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


Re: [Haskell-cafe] Re: Optimization problem

2006-09-28 Thread Ross Paterson
On Thu, Sep 28, 2006 at 03:22:25PM +0100, Simon Peyton-Jones wrote:
 | Does anything go wrong with irrefutable patterns for existential
 types?
 
 Try giving the translation into System F.

Hmm, that's not quite as satisfying as Conor's answer for GADTs.

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


Re: [Haskell-cafe] Re: Optimization problem

2006-09-20 Thread Ross Paterson
On Tue, Sep 19, 2006 at 08:06:07PM +0200, [EMAIL PROTECTED] wrote:
 For our optimization problem, it's only a matter of constructors on the
 right hand side. They should pop out before do not look on any
 arguments, so it's safe to cry so you just know, i'm a Just.

It seems the appropriate encoding would be for the shape to be an
inductive datatype and the contents (as well as the lists) to be
coinductive, as access to the contents is gated through the shape.

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


Re: [Haskell-cafe] Re: Optimization problem

2006-09-19 Thread Ross Paterson
On Tue, Sep 19, 2006 at 01:41:51PM +0200, [EMAIL PROTECTED] wrote:
 Btw, why are there no irrefutable patterns for GADTs?

Not GADTs, but existential types (whether done with GADTs or not).
They can't be analysed with irrefutable patterns, of which let bindings
are a special case:

http://www.haskell.org/ghc/docs/6.4.2/html/users_guide/type-extensions.html#id3143545

See the second restriction.  Irrefutable patterns aren't mentioned
there, but they're the general case.  See also

http://www.haskell.org/pipermail/haskell-cafe/2006-May/015609.html
http://www.haskell.org/pipermail/glasgow-haskell-users/2006-May/010278.html

though I don't buy the rationale there.  Hugs has no such restriction.

 I mean, such a sin should be shame for a non-strict language...

It certainly bites in this case.  We could define

data TLeaf
data TNode s1 s2

data MapShape s k where
SLeaf :: MapShape TLeaf k
SNode :: !Int - k - MapShape s1 k - MapShape s2 k -
MapShape (TNode s1 s2) k

data MapData s a where
DLeaf :: MapData TLeaf a
DNode :: a - MapData s1 a - MapData s2 a -
MapData (TNode s1 s2) a

data InsertResult s k =
forall s'. InsertResult
(MapShape s' k)
(forall a. MapData s' a - (a, MapData s a))

insert :: Ord k = k - MapShape s k - InsertResult s k

and have the compiler check that the transformations on the shape match
the transformations on the data, but first we need to turn lots of lets
into cases and erase the tildes.  Of course the resulting program no
longer works, but it does have verifiably correct transformations.

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


Re: [Haskell-cafe] Re: Optimization problem

2006-09-19 Thread Conor McBride

Hi folks

[EMAIL PROTECTED] wrote:

Btw, why are there no irrefutable patterns for GADTs? I mean, such a sin
should be shame for a non-strict language...
  



Just imagine

 data Eq a b where Refl :: Eq a a

 coerce :: Eq a b - a - b
 coerce ~Refl a = b

coerce undefined True :: String

Bang you're dead. Or rather... Twiddle you're dead.

Moral: in a non-total language, if you're using indexing to act as 
evidence for something, you need to be strict about checking the 
evidence before you act on it, or you will be vulnerable to the 
blandishments of the most appalling liars.


As Randy Pollack used to say to us when we were children, the best thing 
about working in a strongly normalizing language is not having to 
normalize things.


All the best

Conor

This message has been checked for viruses but the contents of an attachment
may still contain software viruses, which could damage your computer system:
you are advised to perform your own checks. Email communications with the
University of Nottingham may be monitored as permitted by UK legislation.

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


Re: [Haskell-cafe] Re: Optimization problem

2006-09-19 Thread Robert Dockins


On Sep 19, 2006, at 8:52 AM, Conor McBride wrote:


Hi folks

[EMAIL PROTECTED] wrote:
Btw, why are there no irrefutable patterns for GADTs? I mean, such  
a sin

should be shame for a non-strict language...




Just imagine

 data Eq a b where Refl :: Eq a a

 coerce :: Eq a b - a - b
 coerce ~Refl a = b



I think you mean:

 coerce ~Refl x = x



coerce undefined True :: String

Bang you're dead. Or rather... Twiddle you're dead.

Moral: in a non-total language, if you're using indexing to act as  
evidence for something, you need to be strict about checking the  
evidence before you act on it, or you will be vulnerable to the  
blandishments of the most appalling liars.


As Randy Pollack used to say to us when we were children, the best  
thing about working in a strongly normalizing language is not  
having to normalize things.


All the best

Conor



Rob Dockins

Speak softly and drive a Sherman tank.
Laugh hard; it's a long way to the bank.
  -- TMBG



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


Re: [Haskell-cafe] Re: Optimization problem

2006-09-19 Thread Conor McBride

Robert Dockins wrote:


On Sep 19, 2006, at 8:52 AM, Conor McBride wrote:


Hi folks

[EMAIL PROTECTED] wrote:
Btw, why are there no irrefutable patterns for GADTs? I mean, such a 
sin

should be shame for a non-strict language...




Just imagine

 data Eq a b where Refl :: Eq a a

 coerce :: Eq a b - a - b
 coerce ~Refl a = b



I think you mean:

 coerce ~Refl x = x


Indeed I do. My original program was much safer!

Thanks

Conor


This message has been checked for viruses but the contents of an attachment
may still contain software viruses, which could damage your computer system:
you are advised to perform your own checks. Email communications with the
University of Nottingham may be monitored as permitted by UK legislation.

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


Re: [Haskell-cafe] Re: Optimization problem

2006-09-18 Thread Ross Paterson
On Sun, Sep 17, 2006 at 01:08:04PM +0200, [EMAIL PROTECTED] wrote:
 Ross Paterson wrote:
  It's interesting that these composed transformations don't seem to cost
  too much.
 
 That the composed transformations are indeed cheap is not necessarily
 disturbing.

I meant the composition of the transformations of the tree (update or
reverse insert) that Bertram does for each list element.  They're cheap
because they're bounded by the depth of the tree, and even cheaper if
you're probing some other part of the tree.

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


Re: [Haskell-cafe] Re: Optimization problem

2006-09-18 Thread Ross Paterson
On Mon, Sep 18, 2006 at 12:23:11AM +0100, Ross Paterson wrote:
 To prove that (even for partial and infinite lists ps)
 
   splitSeq ps = [(a, seconds a ps) | a - nub ps]
 
 [...] we can establish, by induction on the input list,
 
 (1)   fst (splitSeq' s ps) =
   [(a, seconds a ps) | a - nub ps, not (member a s)]
 (2)   member x s  =
   get x s (snd (splitSeq' s ps)) = seconds x ps

Oops, nub ps should be nub (map fst ps) in each case.

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


Re: [Haskell-cafe] Re: Optimization problem

2006-09-17 Thread Ross Paterson
On Thu, Sep 14, 2006 at 07:51:59PM +0200, Bertram Felgenhauer wrote:
 It's a result of thinking about lazy evaluation, and
 especially lazy patterns (and let bindings) for some time. A wiki article
 that helped me a lot to understand these is
 
   http://www.haskell.org/hawiki/TyingTheKnot
 
 I'd like to point out the trustList function there which uses the idea
 of encoding the structure of a term and its actual values in different
 arguments, i.e. a blueprint.

One view of your device is as separating the shape (blueprint) from the
contents, e.g. one can split a finite map type

data Map k a  = Node !Int k a (Map k a) (Map k a) | Leaf

into a pair of types

data MapShape k = SNode !Int k (MapShape k) (MapShape k) | SLeaf
data MapData a = DNode a (MapData a) (MapData a) | DLeaf

(We don't even need DLeaf, as it's never examined.)
We need functions

fill :: a - MapShape k - MapData a
update :: Ord k = k - (a - a) - MapShape k -
MapData a - MapData a
insert :: Ord k = k - MapShape k -
(MapShape k, MapData a - (a, MapData a))

In a dependently typed language we could parameterize MapData with shapes
to give more precise types:

fill :: a - forall s :: MapShape k. MapData s a
update :: Ord k = k - (a - a) -
forall s :: MapShape k.  MapData s a - MapData s a
insert :: Ord k = k - forall s :: MapShape k.
(exists s' :: MapShape k, MapData s' a - (a, MapData s a))

hinting that the function returned by insert reverses the effect of
the insertion.  It's not possible to code this with GADTs, because
existentials are incompatible with irrefutable patterns, at least
in GHC.

Anyway, splitSeq then becomes

splitSeq :: Ord a = [(a,b)] - [(a,[b])]
splitSeq = fst . splitSeq' SLeaf

splitSeq' :: Ord a = MapShape a - [(a,b)] - ([(a,[b])], MapData [b])
splitSeq' bp [] = ([], fill [] bp)
splitSeq' bp ((a,b):xs)
  | member a bp = let (l, m) = splitSeq' bp xs
  in  (l, update a (b:) bp m)
  | otherwise   = let (bp', extract) = insert a bp
  (l, m')= splitSeq' bp' xs
  (bs, m)= extract m'
  in  ((a, b:bs) : l, m)

Again, no knot-tying is required.

To prove that (even for partial and infinite lists ps)

splitSeq ps = [(a, seconds a ps) | a - nub ps]

where

seconds :: Eq a = a - [(a,b)] - [b]
seconds a ps = [b | (a', b) - ps, a' == a]

we need another function

get :: Ord k = k - MapShape k - MapData a - a

and the properties

member k s  =
get k s (fill v s) = v

member k s  =
get k s (update k f s m) = f (get k s m)
member k s /\ member x s /\ x /= k  =
get x s (update k f s m) = get x s m

not (member k s) /\ insert k s = (s', extract)  =
member x s' = member x s || x == k
not (member k s) /\ insert k s = (s', extract)  =
fst (extract m) = get k s' m
not (member k s) /\ insert k s = (s', extract) /\ member x s  =
get x s (snd (extract m)) = get x s' m

Then we can establish, by induction on the input list,

(1) fst (splitSeq' s ps) =
[(a, seconds a ps) | a - nub ps, not (member a s)]
(2) member x s  =
get x s (snd (splitSeq' s ps)) = seconds x ps

This is enough to sustain the induction and obtain the desired property,
but it's a bit inelegant not to have an exact characterization of the
second component.  It seems essential to observe the map data only
though get.

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


Re: [Haskell-cafe] Re: Optimization problem

2006-09-17 Thread Donald Bruce Stewart
ross:
 On Thu, Sep 14, 2006 at 07:51:59PM +0200, Bertram Felgenhauer wrote:
  It's a result of thinking about lazy evaluation, and
  especially lazy patterns (and let bindings) for some time. A wiki article
  that helped me a lot to understand these is
  
http://www.haskell.org/hawiki/TyingTheKnot
  
  I'd like to point out the trustList function there which uses the idea
  of encoding the structure of a term and its actual values in different
  arguments, i.e. a blueprint.
 
 One view of your device is as separating the shape (blueprint) from the
 contents, e.g. one can split a finite map type
 
   data Map k a  = Node !Int k a (Map k a) (Map k a) | Leaf
 
 into a pair of types
 
   data MapShape k = SNode !Int k (MapShape k) (MapShape k) | SLeaf
   data MapData a = DNode a (MapData a) (MapData a) | DLeaf

...

Nice description.

Ross, I added a wiki page for this technique. Would you like to
either elaborate on the wiki, or include the text of your email to it?

http://haskell.org/haskellwiki/Separating_shape_and_content

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


Re: [Haskell-cafe] Re: Optimization problem

2006-09-14 Thread Magnus Jonsson
Thanks Bertran for your solution. I have difficulty understanding it so I 
can't comment on it right now but I'll try to have a look at it. Do you 
know of any article that explains this technique, starting from very 
simple examples?


/Magnus

On Thu, 14 Sep 2006, Bertram Felgenhauer wrote:


I wrote:

[1] Balancing can be done with the information in the blueprint, and
mapping back is easily done by doing the transformation on the tree
in reverse.


I should add that this possibility was the main reason for dealing with
blueprints at all. As Ross Paterson's solution shows, it's possible to
get simpler code without balancing the tree.

regards,

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


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


Re: [Haskell-cafe] Re: Optimization problem

2006-09-14 Thread Bertram Felgenhauer
Magnus Jonsson wrote:
 Thanks Bertran for your solution. I have difficulty understanding it so I 
 can't comment on it right now but I'll try to have a look at it. Do you 
 know of any article that explains this technique, starting from very 
 simple examples?

Not really. It's a result of thinking about lazy evaluation, and
especially lazy patterns (and let bindings) for some time. A wiki article
that helped me a lot to understand these is

  http://www.haskell.org/hawiki/TyingTheKnot

I'd like to point out the trustList function there which uses the idea
of encoding the structure of a term and its actual values in different
arguments, i.e. a blueprint.

HTH,

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