RE: Help with coercion roles?

2014-04-14 Thread Simon Peyton Jones
I think you need a ‘Sub’.

A cast  (e `cast` g) requires a representational coercion.  I think you have 
given it a (stronger) nominal one.  Sub gets from one to t’other.

Simon

From: Glasgow-haskell-users [mailto:glasgow-haskell-users-boun...@haskell.org] 
On Behalf Of Conal Elliott
Sent: 14 April 2014 06:00
To: ghc-d...@haskell.org; glasgow-haskell-users@haskell.org
Subject: Help with coercion  roles?

I’m working on a GHC plugin (as part of my Haskell-to-hardware work) and 
running into trouble with coercions  roles. Error message from Core Lint:

Warning: In the expression:



  LambdaCCC.Lambda.lamvP#

@ (GHC.Types.Bool → GHC.Types.Bool → GHC.Types.Bool → GHC.Types.Bool)

@ (Simple.HasIf GHC.Types.Bool)

tpl#

((LambdaCCC.Lambda.varP#

@ (GHC.Types.Bool → GHC.Types.Bool → GHC.Types.Bool → GHC.Types.Bool)

tpl#)

 `cast` (LambdaCCC.Lambda.EP_N (Sym (Simple.NTCo:HasIf[0] 
GHC.Types.Bool_N))

 ∷ LambdaCCC.Lambda.EP

  (GHC.Types.Bool

   → GHC.Types.Bool → GHC.Types.Bool → GHC.Types.Bool)

  ~#

LambdaCCC.Lambda.EP (Simple.HasIf GHC.Types.Bool)))



Role incompatibility: expected nominal, got representational

in LambdaCCC.Lambda.EP_N (Sym (Simple.NTCo:HasIf[0] GHC.Types.Bool_N))

Do you see anything inconsistent/incompatible in the coercions or roles above? 
I constructed the nominal EP Refl coercion, and applied it (AppCo) an existing 
coercion of a simpler type.

Thanks,
-- Conal
___
Glasgow-haskell-users mailing list
Glasgow-haskell-users@haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users


Re: Help with coercion roles?

2014-04-14 Thread Richard Eisenberg
I agree with Simon, but just `Sub` the `LambdaCCC.Lambda.EP_N`, not the whole 
coercion.

There are actually two problems here. The one Simon identified, and also the 
fact that Simple.NTCo:HasIf[0] produces a representational coercion. How do I 
know? Because of the `NT` -- it's a newtype axiom and must produce 
representational coercions. Furthermore, unless the newtype definition is 
inferred to require a nominal parameter, the newtype would expect a 
representational coercion, not the nominal one you are passing. Check the dump 
(using -ddump-tc) of the newtype axiom to be sure.

Though putting a `Sub` on `EP` and changing the Refl constructor on `Bool` 
would work, you would then be violating an invariant of GHC's Coercion type: 
that we prefer `TyConAppCo tc ...` over `AppCo (Refl (TyConApp tc [])) ...`.

In sum, here is the coercion I think you want:

(LambdaCCC.Lambda.EP (Sym (Simple.NTCo:HasIf[0] GHC.Types.Bool_R)))_R

This is one of the problems with roles -- they are *very* fiddly within GHC, 
and it's hard for a non-expert in roles to get them right.

Have you seen docs/core-spec/core-spec.pdf? That is updated w.r.t. roles and 
may be of help.

Let me know if I can help further!
Richard

On Apr 14, 2014, at 5:45 AM, Simon Peyton Jones simo...@microsoft.com wrote:

 I think you need a ‘Sub’.
  
 A cast  (e `cast` g) requires a representational coercion.  I think you have 
 given it a (stronger) nominal one.  Sub gets from one to t’other.
  
 Simon
  
 From: Glasgow-haskell-users 
 [mailto:glasgow-haskell-users-boun...@haskell.org] On Behalf Of Conal Elliott
 Sent: 14 April 2014 06:00
 To: ghc-d...@haskell.org; glasgow-haskell-users@haskell.org
 Subject: Help with coercion  roles?
  
 I’m working on a GHC plugin (as part of my Haskell-to-hardware work) and 
 running into trouble with coercions  roles. Error message from Core Lint:
 
 Warning: In the expression:
  
   LambdaCCC.Lambda.lamvP#
 @ (GHC.Types.Bool → GHC.Types.Bool → GHC.Types.Bool → GHC.Types.Bool)
 @ (Simple.HasIf GHC.Types.Bool)
 tpl#
 ((LambdaCCC.Lambda.varP#
 @ (GHC.Types.Bool → GHC.Types.Bool → GHC.Types.Bool → GHC.Types.Bool)
 tpl#)
  `cast` (LambdaCCC.Lambda.EP_N (Sym (Simple.NTCo:HasIf[0] 
 GHC.Types.Bool_N))
  ∷ LambdaCCC.Lambda.EP
   (GHC.Types.Bool
→ GHC.Types.Bool → GHC.Types.Bool → GHC.Types.Bool)
   ~#
 LambdaCCC.Lambda.EP (Simple.HasIf GHC.Types.Bool)))
  
 Role incompatibility: expected nominal, got representational
 in LambdaCCC.Lambda.EP_N (Sym (Simple.NTCo:HasIf[0] GHC.Types.Bool_N))
 Do you see anything inconsistent/incompatible in the coercions or roles 
 above? I constructed the nominal EP Refl coercion, and applied it (AppCo) an 
 existing coercion of a simpler type.
 
 Thanks,
 
 -- Conal
 ___
 Glasgow-haskell-users mailing list
 Glasgow-haskell-users@haskell.org
 http://www.haskell.org/mailman/listinfo/glasgow-haskell-users

___
Glasgow-haskell-users mailing list
Glasgow-haskell-users@haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users


Re: Using Cabal to install terminfo-0.4.0.0 breaks GHC on Debian x86_64

2014-04-14 Thread Ramin Honary
I am using Debian, not Mac. It is possible the problem may be with the
binary release for Debian x86_64, or it could just be my Cabal config file.

When I install the binary distribution onto Debian, I simply run make
install in the ghc-7.8.2 directory. I don't know how this install process
the creates the GHC package registry, but after a fresh install, the output
of the ghc-pkg list command shows that terminfo-0.4.0.0 is NOT
installed even though there the /usr/local/lib/ghc-7.8.2/terminfo-0.4.0.0
directory clearly exists and is populated with the correct library files.
But since it is not registered Cabal tries to re-build it and overwrites
the existing terminfo-0.4.0.0 package.

After a fresh install on Mac or Fedora, I wonder if terminfo-0.4.0.0
shows up in the GHC package registry? It could be the package registry for
the Debian binary distribution missed that detail.
___
Glasgow-haskell-users mailing list
Glasgow-haskell-users@haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users


Re: Using Cabal to install terminfo-0.4.0.0 breaks GHC on Debian x86_64

2014-04-14 Thread Austin Seipp
Hi Ramin,

Can I ask if you're installing packages into the global user database?
If so, that's definitely the way for this to happen - otherwise, Cabal
should never overwrite *anything* in the 'global' package directory
(in your case, under /usr/local/lib/ghc-7.8.2...) This is the only way
I can see this happening. In particular, installing 'terminfo' into my
local package database ('cabal install terminfo') works fine...

Carefully review your cabal configuration if you don't mind. You can
also always force the installation using '--user' when running cabal.

However, thank you very much for bringing this to my attention. What
you have discovered is a real brainfart I don't think we had
considered! The problem is that now that GHC is dynamically linked, we
*cannot* get away with lying about whether those packages are
installed - because they must install shared objects for GHC itself to
work. That means overwriting them by accident (because we don't think
they're installed) is a real possibility.

Relatedly, the NixOS Haskell users are suffering from the same problem
with 7.8.2 - http://lists.science.uu.nl/pipermail/nix-dev/2014-April/012992.html
- same problem, slightly different symptoms.

See https://ghc.haskell.org/trac/ghc/ticket/8919 for the ticket.

So this is definitely a real problem. I think scheduling the change
for 7.8.3 is correct.

My intuition tells me the fix might actually be quite simple - don't
lie about xhtml and terminfo being installed, and just be honest. Is
there any particular downside to doing this? I don't think so, *other*
than the fact it does mean terminfo has to come along when it's not
part of the Haskell Platform!



On Mon, Apr 14, 2014 at 7:08 AM, Ramin Honary ramin.hon...@gmail.com wrote:
 I am using Debian, not Mac. It is possible the problem may be with the
 binary release for Debian x86_64, or it could just be my Cabal config file.

 When I install the binary distribution onto Debian, I simply run make
 install in the ghc-7.8.2 directory. I don't know how this install process
 the creates the GHC package registry, but after a fresh install, the output
 of the ghc-pkg list command shows that terminfo-0.4.0.0 is NOT installed
 even though there the /usr/local/lib/ghc-7.8.2/terminfo-0.4.0.0 directory
 clearly exists and is populated with the correct library files. But since it
 is not registered Cabal tries to re-build it and overwrites the existing
 terminfo-0.4.0.0 package.

 After a fresh install on Mac or Fedora, I wonder if terminfo-0.4.0.0 shows
 up in the GHC package registry? It could be the package registry for the
 Debian binary distribution missed that detail.


 ___
 Glasgow-haskell-users mailing list
 Glasgow-haskell-users@haskell.org
 http://www.haskell.org/mailman/listinfo/glasgow-haskell-users




-- 
Regards,

Austin Seipp, Haskell Consultant
Well-Typed LLP, http://www.well-typed.com/
___
Glasgow-haskell-users mailing list
Glasgow-haskell-users@haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users


Re: -optl behavior in ghc-7.8.1

2014-04-14 Thread Simon Marlow

On 10/04/2014 18:11, Yuras Shumovich wrote:

On Thu, 2014-04-10 at 18:49 +0200, Karel Gardas wrote:

On 04/10/14 06:39 PM, Yuras Shumovich wrote:

...and other linker options must come after, like in my case. So what?
Are there any ticket where people complain about the old behavior? I'm
not advocating any specific behavior, I'm just asking why it was
changed.


Hmm, I'm not sure if I'm the patch provider, but at least I provided
patch which was merged into HEAD (don't have 7.8 branch here so check
yourself) which fixes linking of binaries failure on Solaris. Please see
b9b94ec82d9125da47c619c69e626120b3e60457

The core of the change is:

-else package_hs_libs ++ extra_libs ++ other_flags
+else other_flags ++ package_hs_libs ++ extra_libs


Thank you for pointing to the commit. I hoped it was incidental change,
but now I see the reason.


Actually this was me: 
https://ghc.haskell.org/trac/ghc/changeset/1e2b3780ebc40d28cd0f029b90df102df09e6827/ghc


The problem I was fixing was that we weren't always passing the -optl 
options.  Now when we invoke a program the -optXXX options always come 
first - I think before it was kind of random and different for each of 
the phases.


Cheers,
Simon





Thanks,
Yuras



the patch contains full explanation in comment so see it for more
information.

If this is not what bugs you, then please ignore me.

Thanks,
Karel



___
Glasgow-haskell-users mailing list
Glasgow-haskell-users@haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users


a
___
Glasgow-haskell-users mailing list
Glasgow-haskell-users@haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users


Re: -optl behavior in ghc-7.8.1

2014-04-14 Thread Brandon Allbery
On Mon, Apr 14, 2014 at 10:42 AM, Simon Marlow marlo...@gmail.com wrote:

 The problem I was fixing was that we weren't always passing the -optl
 options.  Now when we invoke a program the -optXXX options always come
 first - I think before it was kind of random and different for each of the
 phases.


Some things do need to come first, like that; but apparently we need either
after-options or a more flexible library syntax. (Or an other-objects?)

-- 
brandon s allbery kf8nh   sine nomine associates
allber...@gmail.com  ballb...@sinenomine.net
unix, openafs, kerberos, infrastructure, xmonadhttp://sinenomine.net
___
Glasgow-haskell-users mailing list
Glasgow-haskell-users@haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users


Fwd: Using Cabal to install terminfo-0.4.0.0 breaks GHC on Debian x86_64

2014-04-14 Thread Ramin Honary
Hi, thanks for your reply.

Yes, I know for a fact I was installing to the global registry. All of my
Haskell projects depend on a few important packages, and I always install
these globally. For stuff I just want to play around with, I just install
into the user registry. Actually terminfo-0.4.0.0 is not something any of
my projects depend on, but I had installed it globally anyway and then this
problem occurred.

Also, the behavior Cabal installing Crypto-4.2.5.1 was odd. As I explained
in my first e-mail, some of the shared modules were being built with file
extensions of .hi instead of .dyn_hi, but the copy phase of the Cabal
installation was searching for files with .dyn_hi extensions and was
failing. And not all modules were being built incorrectly, some modules had
the correct .dyn_hi, others had just .hi. This may be a problem with
the Crypto.cabal file, however.

But anyway, the transition to using shared libraries by default has (in my
experience) caused just these two hiccups. I'm glad I was able to expose
this problem.

-- Ramin Honary



On Mon, Apr 14, 2014 at 10:07 PM, Austin Seipp aus...@well-typed.comwrote:

 Hi Ramin,

 Can I ask if you're installing packages into the global user database?
 If so, that's definitely the way for this to happen - otherwise, Cabal
 should never overwrite *anything* in the 'global' package directory
 (in your case, under /usr/local/lib/ghc-7.8.2...) This is the only way
 I can see this happening. In particular, installing 'terminfo' into my
 local package database ('cabal install terminfo') works fine...

 Carefully review your cabal configuration if you don't mind. You can
 also always force the installation using '--user' when running cabal.

 However, thank you very much for bringing this to my attention. What
 you have discovered is a real brainfart I don't think we had
 considered! The problem is that now that GHC is dynamically linked, we
 *cannot* get away with lying about whether those packages are
 installed - because they must install shared objects for GHC itself to
 work. That means overwriting them by accident (because we don't think
 they're installed) is a real possibility.

 Relatedly, the NixOS Haskell users are suffering from the same problem
 with 7.8.2 -
 http://lists.science.uu.nl/pipermail/nix-dev/2014-April/012992.html
 - same problem, slightly different symptoms.

 See https://ghc.haskell.org/trac/ghc/ticket/8919 for the ticket.

 So this is definitely a real problem. I think scheduling the change
 for 7.8.3 is correct.

 My intuition tells me the fix might actually be quite simple - don't
 lie about xhtml and terminfo being installed, and just be honest. Is
 there any particular downside to doing this? I don't think so, *other*
 than the fact it does mean terminfo has to come along when it's not
 part of the Haskell Platform!



 On Mon, Apr 14, 2014 at 7:08 AM, Ramin Honary ramin.hon...@gmail.com
 wrote:
  I am using Debian, not Mac. It is possible the problem may be with the
  binary release for Debian x86_64, or it could just be my Cabal config
 file.
 
  When I install the binary distribution onto Debian, I simply run make
  install in the ghc-7.8.2 directory. I don't know how this install
 process
  the creates the GHC package registry, but after a fresh install, the
 output
  of the ghc-pkg list command shows that terminfo-0.4.0.0 is NOT
 installed
  even though there the /usr/local/lib/ghc-7.8.2/terminfo-0.4.0.0 directory
  clearly exists and is populated with the correct library files. But
 since it
  is not registered Cabal tries to re-build it and overwrites the existing
  terminfo-0.4.0.0 package.
 
  After a fresh install on Mac or Fedora, I wonder if terminfo-0.4.0.0
 shows
  up in the GHC package registry? It could be the package registry for the
  Debian binary distribution missed that detail.
 
 
  ___
  Glasgow-haskell-users mailing list
  Glasgow-haskell-users@haskell.org
  http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
 



 --
 Regards,

 Austin Seipp, Haskell Consultant
 Well-Typed LLP, http://www.well-typed.com/

___
Glasgow-haskell-users mailing list
Glasgow-haskell-users@haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users


Re: Help with coercion roles?

2014-04-14 Thread Conal Elliott
Thanks for the pointers! I don't quite know how to get to the form you
recommend from the existing coercion, which is `Simple.NTCo:HasIf[0]
GHC.Types.Bool_N`. (Note the `_N`.) I got that coercion in GHC 7.8.2 from
the following code:

 class HasIf a where
   ifThenElse :: Bool - a - a - a

 instance HasIf Bool where
   ifThenElse i t e = (i  t) || (not i  e)

With `--dump-tc`, I see

 TYPE SIGNATURES
 TYPE CONSTRUCTORS
   HasIf :: * - Constraint
   class HasIf a
 Roles: [nominal]
 RecFlag NonRecursive
 ifThenElse :: Bool - a - a - a
 COERCION AXIOMS
   axiom Main.NTCo:HasIf :: HasIf a = Bool - a - a - a
 INSTANCES
   instance HasIf Bool -- Defined at ../test/HasIf.hs:4:10

Do I need to convert the nominal coercion I got from GHC
(`Simple.NTCo:HasIf[0] GHC.Types.Bool_N` in this case) to a
representational one? If so, how?
My current formulation (tweaked to use `mkSubCo` and `mkAppCo`) is to apply
`mkAppCo (mkSubCo (Refl Nominal ep))` to the given coercion, which then
produces

 (LambdaCCC.Lambda.EP (Sym (Simple.NTCo:HasIf[0] GHC.Types.Bool_N)))_R

And still I get Role incompatibility: expected nominal, got
representational in `Sym (Simple.NTCo:HasIf[0] GHC.Types.Bool_N)`.

I also tried wrapping `mkSubCo` around the entire coercion (applying
`mkSubCo . mkAppCo (Refl Nominal ep)`), and I see the same result:

 (LambdaCCC.Lambda.EP (Sym (Simple.NTCo:HasIf[0] GHC.Types.Bool_N)))_R

-- Conal



On Mon, Apr 14, 2014 at 4:39 AM, Richard Eisenberg e...@cis.upenn.eduwrote:

 I agree with Simon, but just `Sub` the `LambdaCCC.Lambda.EP_N`, not the
 whole coercion.

 There are actually two problems here. The one Simon identified, and also
 the fact that Simple.NTCo:HasIf[0] produces a representational coercion.
 How do I know? Because of the `NT` -- it's a newtype axiom and must produce
 representational coercions. Furthermore, unless the newtype definition is
 inferred to require a nominal parameter, the newtype would expect a
 representational coercion, not the nominal one you are passing. Check the
 dump (using -ddump-tc) of the newtype axiom to be sure.

 Though putting a `Sub` on `EP` and changing the Refl constructor on
 `Bool` would work, you would then be violating an invariant of GHC's
 Coercion type: that we prefer `TyConAppCo tc ...` over `AppCo (Refl
 (TyConApp tc [])) ...`.

 In sum, here is the coercion I think you want:

 (LambdaCCC.Lambda.EP (Sym (Simple.NTCo:HasIf[0] GHC.Types.Bool_R)))_R

 This is one of the problems with roles -- they are *very* fiddly within
 GHC, and it's hard for a non-expert in roles to get them right.

 Have you seen docs/core-spec/core-spec.pdf? That is updated w.r.t. roles
 and may be of help.

 Let me know if I can help further!
 Richard

 On Apr 14, 2014, at 5:45 AM, Simon Peyton Jones simo...@microsoft.com
 wrote:

 I think you need a ‘Sub’.

 A cast  (e `cast` g) requires a representational coercion.  I think you
 have given it a (stronger) nominal one.  Sub gets from one to t’other.

 Simon

  *From:* Glasgow-haskell-users [mailto:glasgow-
 haskell-users-boun...@haskell.org] *On Behalf Of *Conal Elliott
 *Sent:* 14 April 2014 06:00
 *To:* ghc-d...@haskell.org; glasgow-haskell-users@haskell.org
 *Subject:* Help with coercion  roles?


 I’m working on a GHC plugin (as part of my Haskell-to-hardware work) and
 running into trouble with coercions  roles. Error message from Core Lint:

 Warning: In the expression:



   LambdaCCC.Lambda.lamvP#

 @ (GHC.Types.Bool → GHC.Types.Bool → GHC.Types.Bool → GHC.Types.Bool)

 @ (Simple.HasIf GHC.Types.Bool)

 tpl#

 ((LambdaCCC.Lambda.varP#

 @ (GHC.Types.Bool → GHC.Types.Bool → GHC.Types.Bool → GHC.Types.Bool)

 tpl#)

  `cast` (LambdaCCC.Lambda.EP_N (Sym (Simple.NTCo:HasIf[0] 
 GHC.Types.Bool_N))

  ∷ LambdaCCC.Lambda.EP

   (GHC.Types.Bool

→ GHC.Types.Bool → GHC.Types.Bool → GHC.Types.Bool)

   ~#

 LambdaCCC.Lambda.EP (Simple.HasIf GHC.Types.Bool)))

  Role incompatibility: expected nominal, got representational

 in LambdaCCC.Lambda.EP_N (Sym (Simple.NTCo:HasIf[0] GHC.Types.Bool_N))

 Do you see anything inconsistent/incompatible in the coercions or roles
 above? I constructed the nominal EP Refl coercion, and applied it (AppCo)
 an existing coercion of a simpler type.

 Thanks,
 -- Conal
 ___
 Glasgow-haskell-users mailing list
 Glasgow-haskell-users@haskell.org
 http://www.haskell.org/mailman/listinfo/glasgow-haskell-users



___
Glasgow-haskell-users mailing list
Glasgow-haskell-users@haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users


Re: Help with coercion roles?

2014-04-14 Thread Richard Eisenberg
Hi Conal,

In your case, the `_N` on the argument to NTCo:HasIf[0] is correct -- the 
`HasIf` class indeed has a nominal parameter. So, it seems that this part, at 
least, is OK.

What's the -ddump-tc on EP? Is EP's role nominal? (I think so, given what 
you're saying.) If that's the case, you won't be able to pass the result of 
NTCo:HasIf[0] to a coercion built from EP.

Popping up a level, what are you trying to do here? If EP's role is indeed 
nominal, then I don't believe there's a fix here, as the coercion it seems 
you're trying to build may be unsound. (It looks to me like you want something 
proving `EP (Bool - Bool - Bool - Bool) ~R EP (HasIf Bool)`, but if EP's 
role is nominal, then this is indeed bogus.)

Richard

On Apr 14, 2014, at 2:23 PM, Conal Elliott co...@conal.net wrote:

 Thanks for the pointers! I don't quite know how to get to the form you 
 recommend from the existing coercion, which is `Simple.NTCo:HasIf[0] 
 GHC.Types.Bool_N`. (Note the `_N`.) I got that coercion in GHC 7.8.2 from 
 the following code:
 
  class HasIf a where
ifThenElse :: Bool - a - a - a
 
  instance HasIf Bool where
ifThenElse i t e = (i  t) || (not i  e)
 
 With `--dump-tc`, I see
 
  TYPE SIGNATURES
  TYPE CONSTRUCTORS
HasIf :: * - Constraint
class HasIf a
  Roles: [nominal]
  RecFlag NonRecursive
  ifThenElse :: Bool - a - a - a
  COERCION AXIOMS
axiom Main.NTCo:HasIf :: HasIf a = Bool - a - a - a
  INSTANCES
instance HasIf Bool -- Defined at ../test/HasIf.hs:4:10
 
 Do I need to convert the nominal coercion I got from GHC 
 (`Simple.NTCo:HasIf[0] GHC.Types.Bool_N` in this case) to a 
 representational one? If so, how?
 My current formulation (tweaked to use `mkSubCo` and `mkAppCo`) is to apply 
 `mkAppCo (mkSubCo (Refl Nominal ep))` to the given coercion, which then 
 produces
 
  (LambdaCCC.Lambda.EP (Sym (Simple.NTCo:HasIf[0] GHC.Types.Bool_N)))_R
 
 And still I get Role incompatibility: expected nominal, got representational 
 in `Sym (Simple.NTCo:HasIf[0] GHC.Types.Bool_N)`.
 
 I also tried wrapping `mkSubCo` around the entire coercion (applying `mkSubCo 
 . mkAppCo (Refl Nominal ep)`), and I see the same result:
 
  (LambdaCCC.Lambda.EP (Sym (Simple.NTCo:HasIf[0] GHC.Types.Bool_N)))_R
 
 -- Conal
 
 
 On Mon, Apr 14, 2014 at 4:39 AM, Richard Eisenberg e...@cis.upenn.edu wrote:
 I agree with Simon, but just `Sub` the `LambdaCCC.Lambda.EP_N`, not the 
 whole coercion.
 
 There are actually two problems here. The one Simon identified, and also the 
 fact that Simple.NTCo:HasIf[0] produces a representational coercion. How do I 
 know? Because of the `NT` -- it's a newtype axiom and must produce 
 representational coercions. Furthermore, unless the newtype definition is 
 inferred to require a nominal parameter, the newtype would expect a 
 representational coercion, not the nominal one you are passing. Check the 
 dump (using -ddump-tc) of the newtype axiom to be sure.
 
 Though putting a `Sub` on `EP` and changing the Refl constructor on 
 `Bool` would work, you would then be violating an invariant of GHC's 
 Coercion type: that we prefer `TyConAppCo tc ...` over `AppCo (Refl (TyConApp 
 tc [])) ...`.
 
 In sum, here is the coercion I think you want:
 
 (LambdaCCC.Lambda.EP (Sym (Simple.NTCo:HasIf[0] GHC.Types.Bool_R)))_R
 
 This is one of the problems with roles -- they are *very* fiddly within GHC, 
 and it's hard for a non-expert in roles to get them right.
 
 Have you seen docs/core-spec/core-spec.pdf? That is updated w.r.t. roles and 
 may be of help.
 
 Let me know if I can help further!
 Richard
 
 On Apr 14, 2014, at 5:45 AM, Simon Peyton Jones simo...@microsoft.com wrote:
 
 I think you need a ‘Sub’.
  
 A cast  (e `cast` g) requires a representational coercion.  I think you have 
 given it a (stronger) nominal one.  Sub gets from one to t’other.
  
 Simon
  
 From: Glasgow-haskell-users 
 [mailto:glasgow-haskell-users-boun...@haskell.org] On Behalf Of Conal Elliott
 Sent: 14 April 2014 06:00
 To: ghc-d...@haskell.org; glasgow-haskell-users@haskell.org
 Subject: Help with coercion  roles?
  
 I’m working on a GHC plugin (as part of my Haskell-to-hardware work) and 
 running into trouble with coercions  roles. Error message from Core Lint:
 
 Warning: In the expression:
 
  
   LambdaCCC.Lambda.lamvP#
 @ (GHC.Types.Bool → GHC.Types.Bool → GHC.Types.Bool → GHC.Types.Bool)
 @ (Simple.HasIf GHC.Types.Bool)
 
 tpl#
 ((LambdaCCC.Lambda.varP#
 @ (GHC.Types.Bool → GHC.Types.Bool → GHC.Types.Bool → GHC.Types.Bool)
 tpl#)
 
  `cast` (LambdaCCC.Lambda.EP_N (Sym (Simple.NTCo:HasIf[0] 
 GHC.Types.Bool_N))
 
  ∷ LambdaCCC.Lambda.EP
   (GHC.Types.Bool
 
→ GHC.Types.Bool → GHC.Types.Bool → GHC.Types.Bool)
 
   ~#
 LambdaCCC.Lambda.EP (Simple.HasIf GHC.Types.Bool)))
  
 
 Role incompatibility: expected nominal, got representational
 
 in LambdaCCC.Lambda.EP_N 

Re: Help with coercion roles?

2014-04-14 Thread Conal Elliott
Hi Richard,

I'm working on compiling Haskell to hardware, as outlined at
https://github.com/conal/lambda-ccc/blob/master/doc/notes.md (with links to
a few recent blog posts). The first step is to convert Core into other Core
that evaluates to a reified form, represented as a type-parametrized GADT.
This GADT (in `LambdaCCC.Lambda`):

 data E :: (* - *) - (* - *) where ...

The parameter is also type-parametrized, and is for the primitives. I have
such a type designed for hardware generation (in `LambdaCCC.Prim`)

 data Prim :: * - * where ...

and then the combination of the two:

 type EP = E Prim

So that's what `EP` is.

With `-ddump-tc`, I get

 TYPE CONSTRUCTORS
   ...
   E :: (* - *) - * - *
   data E ($a::* - *) $b
 No C type associated
 Roles: [representational, nominal]
 RecFlag NonRecursive, Not promotable
 = ...
   EP :: * - *
   type EP = E Prim

The use of `EP` rather than the more general `E` is only temporary, while
I'm learning more details of Core (and of HERMIT which I'm using to
manipulate Core).

I'm now working on reification in the presence of casts. The rule I'm
trying to implement is

 evalEP e | co  --  evalEP (e | co').

Here, `evalEP :: EP a - a` and `co :: a ~ b`, so `co' :: EP a ~ EP b`.

I'm trying to build `co'` from `co`, which led to these questions.

So what do you think? Is there a sound coercion I can build for `co'`?

-- Conal


On Mon, Apr 14, 2014 at 11:54 AM, Richard Eisenberg e...@cis.upenn.eduwrote:

 Hi Conal,

 In your case, the `_N` on the argument to NTCo:HasIf[0] is correct -- the
 `HasIf` class indeed has a nominal parameter. So, it seems that this part,
 at least, is OK.

 What's the -ddump-tc on EP? Is EP's role nominal? (I think so, given what
 you're saying.) If that's the case, you won't be able to pass the result of
 NTCo:HasIf[0] to a coercion built from EP.

 Popping up a level, what are you trying to do here? If EP's role is indeed
 nominal, then I don't believe there's a fix here, as the coercion it seems
 you're trying to build may be unsound. (It looks to me like you want
 something proving `EP (Bool - Bool - Bool - Bool) ~R EP (HasIf Bool)`,
 but if EP's role is nominal, then this is indeed bogus.)

 Richard

 On Apr 14, 2014, at 2:23 PM, Conal Elliott co...@conal.net wrote:

 Thanks for the pointers! I don't quite know how to get to the form you
 recommend from the existing coercion, which is `Simple.NTCo:HasIf[0]
 GHC.Types.Bool_N`. (Note the `_N`.) I got that coercion in GHC 7.8.2 from
 the following code:

  class HasIf a where
ifThenElse :: Bool - a - a - a
 
  instance HasIf Bool where
ifThenElse i t e = (i  t) || (not i  e)

 With `--dump-tc`, I see

  TYPE SIGNATURES
  TYPE CONSTRUCTORS
HasIf :: * - Constraint
class HasIf a
  Roles: [nominal]
  RecFlag NonRecursive
  ifThenElse :: Bool - a - a - a
  COERCION AXIOMS
axiom Main.NTCo:HasIf :: HasIf a = Bool - a - a - a
  INSTANCES
instance HasIf Bool -- Defined at ../test/HasIf.hs:4:10

 Do I need to convert the nominal coercion I got from GHC
 (`Simple.NTCo:HasIf[0] GHC.Types.Bool_N` in this case) to a
 representational one? If so, how?
 My current formulation (tweaked to use `mkSubCo` and `mkAppCo`) is to
 apply `mkAppCo (mkSubCo (Refl Nominal ep))` to the given coercion, which
 then produces

  (LambdaCCC.Lambda.EP (Sym (Simple.NTCo:HasIf[0] GHC.Types.Bool_N)))_R

 And still I get Role incompatibility: expected nominal, got
 representational in `Sym (Simple.NTCo:HasIf[0] GHC.Types.Bool_N)`.

 I also tried wrapping `mkSubCo` around the entire coercion (applying
 `mkSubCo . mkAppCo (Refl Nominal ep)`), and I see the same result:

  (LambdaCCC.Lambda.EP (Sym (Simple.NTCo:HasIf[0] GHC.Types.Bool_N)))_R

 -- Conal



 On Mon, Apr 14, 2014 at 4:39 AM, Richard Eisenberg e...@cis.upenn.eduwrote:

 I agree with Simon, but just `Sub` the `LambdaCCC.Lambda.EP_N`, not the
 whole coercion.

 There are actually two problems here. The one Simon identified, and also
 the fact that Simple.NTCo:HasIf[0] produces a representational coercion.
 How do I know? Because of the `NT` -- it's a newtype axiom and must produce
 representational coercions. Furthermore, unless the newtype definition is
 inferred to require a nominal parameter, the newtype would expect a
 representational coercion, not the nominal one you are passing. Check the
 dump (using -ddump-tc) of the newtype axiom to be sure.

 Though putting a `Sub` on `EP` and changing the Refl constructor on
 `Bool` would work, you would then be violating an invariant of GHC's
 Coercion type: that we prefer `TyConAppCo tc ...` over `AppCo (Refl
 (TyConApp tc [])) ...`.

 In sum, here is the coercion I think you want:

 (LambdaCCC.Lambda.EP (Sym (Simple.NTCo:HasIf[0] GHC.Types.Bool_R)))_R

 This is one of the problems with roles -- they are *very* fiddly within
 GHC, and it's hard for a non-expert in roles to get them right.

 Have you seen docs/core-spec/core-spec.pdf? That is updated w.r.t. roles
 and may 

Re: Help with coercion roles?

2014-04-14 Thread Richard Eisenberg
 So what do you think? Is there a sound coercion I can build for `co'`?


In a word, no. The problem is that E, as you describe, is a GADT. Therefore, 
it cares exactly which types it is parameterized by. We can see this in 
evidence in the dump, which labels E's second parameter as nominal. To draw out 
the problem, let's look at a simpler example:

 newtype Age = MkAge Int
 data G a where
   MkGInt :: G Int
   MkGAge :: G Age

Here, `G` would similarly get a nominal role, because we can't lift 
representational coercions (such as NTCo:Age :: Age ~R Int) through the `G` 
type constructor. If we could, we could then have (MkGAge | ...) :: G Int, 
which goes against our definition of G -- the only value inhabitant of G Int 
should be MkGInt.

The best you can do here is to try to raise the inner coercion to be nominal, 
by unSubCo_maybe. If that fails, I think you've gone beyond the ability of 
GHC's type system.

Of course, I would like to help you with a way forward -- let me know if 
there's a way I can.

Richard

On Apr 14, 2014, at 4:12 PM, Conal Elliott co...@conal.net wrote:

 Hi Richard,
 
 I'm working on compiling Haskell to hardware, as outlined at 
 https://github.com/conal/lambda-ccc/blob/master/doc/notes.md (with links to a 
 few recent blog posts). The first step is to convert Core into other Core 
 that evaluates to a reified form, represented as a type-parametrized GADT. 
 This GADT (in `LambdaCCC.Lambda`):
 
  data E :: (* - *) - (* - *) where ...
 
 The parameter is also type-parametrized, and is for the primitives. I have 
 such a type designed for hardware generation (in `LambdaCCC.Prim`)
 
  data Prim :: * - * where ...
 
 and then the combination of the two:
 
  type EP = E Prim
 
 So that's what `EP` is.
 
 With `-ddump-tc`, I get
 
  TYPE CONSTRUCTORS
...
E :: (* - *) - * - *
data E ($a::* - *) $b
  No C type associated
  Roles: [representational, nominal]
  RecFlag NonRecursive, Not promotable
  = ...
EP :: * - *
type EP = E Prim
 
 The use of `EP` rather than the more general `E` is only temporary, while I'm 
 learning more details of Core (and of HERMIT which I'm using to manipulate 
 Core).
 
 I'm now working on reification in the presence of casts. The rule I'm trying 
 to implement is
 
  evalEP e | co  --  evalEP (e | co').
 
 Here, `evalEP :: EP a - a` and `co :: a ~ b`, so `co' :: EP a ~ EP b`.
 
 I'm trying to build `co'` from `co`, which led to these questions.
 
 So what do you think? Is there a sound coercion I can build for `co'`?
 
 -- Conal
 
 
 On Mon, Apr 14, 2014 at 11:54 AM, Richard Eisenberg e...@cis.upenn.edu 
 wrote:
 Hi Conal,
 
 In your case, the `_N` on the argument to NTCo:HasIf[0] is correct -- the 
 `HasIf` class indeed has a nominal parameter. So, it seems that this part, at 
 least, is OK.
 
 What's the -ddump-tc on EP? Is EP's role nominal? (I think so, given what 
 you're saying.) If that's the case, you won't be able to pass the result of 
 NTCo:HasIf[0] to a coercion built from EP.
 
 Popping up a level, what are you trying to do here? If EP's role is indeed 
 nominal, then I don't believe there's a fix here, as the coercion it seems 
 you're trying to build may be unsound. (It looks to me like you want 
 something proving `EP (Bool - Bool - Bool - Bool) ~R EP (HasIf Bool)`, but 
 if EP's role is nominal, then this is indeed bogus.)
 
 Richard
 
 On Apr 14, 2014, at 2:23 PM, Conal Elliott co...@conal.net wrote:
 
 Thanks for the pointers! I don't quite know how to get to the form you 
 recommend from the existing coercion, which is `Simple.NTCo:HasIf[0] 
 GHC.Types.Bool_N`. (Note the `_N`.) I got that coercion in GHC 7.8.2 from 
 the following code:
 
  class HasIf a where
ifThenElse :: Bool - a - a - a
 
  instance HasIf Bool where
ifThenElse i t e = (i  t) || (not i  e)
 
 With `--dump-tc`, I see
 
  TYPE SIGNATURES
  TYPE CONSTRUCTORS
HasIf :: * - Constraint
class HasIf a
  Roles: [nominal]
  RecFlag NonRecursive
  ifThenElse :: Bool - a - a - a
  COERCION AXIOMS
axiom Main.NTCo:HasIf :: HasIf a = Bool - a - a - a
  INSTANCES
instance HasIf Bool -- Defined at ../test/HasIf.hs:4:10
 
 Do I need to convert the nominal coercion I got from GHC 
 (`Simple.NTCo:HasIf[0] GHC.Types.Bool_N` in this case) to a 
 representational one? If so, how?
 My current formulation (tweaked to use `mkSubCo` and `mkAppCo`) is to apply 
 `mkAppCo (mkSubCo (Refl Nominal ep))` to the given coercion, which then 
 produces
 
  (LambdaCCC.Lambda.EP (Sym (Simple.NTCo:HasIf[0] GHC.Types.Bool_N)))_R
 
 And still I get Role incompatibility: expected nominal, got 
 representational in `Sym (Simple.NTCo:HasIf[0] GHC.Types.Bool_N)`.
 
 I also tried wrapping `mkSubCo` around the entire coercion (applying 
 `mkSubCo . mkAppCo (Refl Nominal ep)`), and I see the same result:
 
  (LambdaCCC.Lambda.EP (Sym (Simple.NTCo:HasIf[0] GHC.Types.Bool_N)))_R
 
 -- Conal
 
 
 On Mon, Apr 14, 2014 at 4:39 AM, Richard Eisenberg 

Re: Help with coercion roles?

2014-04-14 Thread Conal Elliott
This explanation-with-example is very helpful. Thanks, Richard! I'll noodle
some more. A fairly simple  robust solution may be to add `Cast` to my
expression GADT.

-- Conal


On Mon, Apr 14, 2014 at 2:02 PM, Richard Eisenberg e...@cis.upenn.eduwrote:

 So what do you think? Is there a sound coercion I can build for `co'`?


 In a word, no. The problem is that E, as you describe, is a GADT.
 Therefore, it cares exactly which types it is parameterized by. We can see
 this in evidence in the dump, which labels E's second parameter as nominal.
 To draw out the problem, let's look at a simpler example:

  newtype Age = MkAge Int
  data G a where
MkGInt :: G Int
MkGAge :: G Age

 Here, `G` would similarly get a nominal role, because we can't lift
 representational coercions (such as NTCo:Age :: Age ~R Int) through the `G`
 type constructor. If we could, we could then have (MkGAge | ...) :: G Int,
 which goes against our definition of G -- the only value inhabitant of G
 Int should be MkGInt.

 The best you can do here is to try to raise the inner coercion to be
 nominal, by unSubCo_maybe. If that fails, I think you've gone beyond the
 ability of GHC's type system.

 Of course, I would like to help you with a way forward -- let me know if
 there's a way I can.

 Richard

 On Apr 14, 2014, at 4:12 PM, Conal Elliott co...@conal.net wrote:

 Hi Richard,

 I'm working on compiling Haskell to hardware, as outlined at
 https://github.com/conal/lambda-ccc/blob/master/doc/notes.md (with links
 to a few recent blog posts). The first step is to convert Core into other
 Core that evaluates to a reified form, represented as a type-parametrized
 GADT. This GADT (in `LambdaCCC.Lambda`):

  data E :: (* - *) - (* - *) where ...

 The parameter is also type-parametrized, and is for the primitives. I have
 such a type designed for hardware generation (in `LambdaCCC.Prim`)

  data Prim :: * - * where ...

 and then the combination of the two:

  type EP = E Prim

 So that's what `EP` is.

 With `-ddump-tc`, I get

  TYPE CONSTRUCTORS
...
E :: (* - *) - * - *
data E ($a::* - *) $b
  No C type associated
  Roles: [representational, nominal]
  RecFlag NonRecursive, Not promotable
  = ...
EP :: * - *
type EP = E Prim

 The use of `EP` rather than the more general `E` is only temporary, while
 I'm learning more details of Core (and of HERMIT which I'm using to
 manipulate Core).

 I'm now working on reification in the presence of casts. The rule I'm
 trying to implement is

  evalEP e | co  --  evalEP (e | co').

 Here, `evalEP :: EP a - a` and `co :: a ~ b`, so `co' :: EP a ~ EP b`.

 I'm trying to build `co'` from `co`, which led to these questions.

 So what do you think? Is there a sound coercion I can build for `co'`?

 -- Conal


 On Mon, Apr 14, 2014 at 11:54 AM, Richard Eisenberg e...@cis.upenn.eduwrote:

 Hi Conal,

 In your case, the `_N` on the argument to NTCo:HasIf[0] is correct -- the
 `HasIf` class indeed has a nominal parameter. So, it seems that this part,
 at least, is OK.

 What's the -ddump-tc on EP? Is EP's role nominal? (I think so, given what
 you're saying.) If that's the case, you won't be able to pass the result of
 NTCo:HasIf[0] to a coercion built from EP.

 Popping up a level, what are you trying to do here? If EP's role is
 indeed nominal, then I don't believe there's a fix here, as the coercion it
 seems you're trying to build may be unsound. (It looks to me like you want
 something proving `EP (Bool - Bool - Bool - Bool) ~R EP (HasIf Bool)`,
 but if EP's role is nominal, then this is indeed bogus.)

 Richard

 On Apr 14, 2014, at 2:23 PM, Conal Elliott co...@conal.net wrote:

 Thanks for the pointers! I don't quite know how to get to the form you
 recommend from the existing coercion, which is `Simple.NTCo:HasIf[0]
 GHC.Types.Bool_N`. (Note the `_N`.) I got that coercion in GHC 7.8.2 from
 the following code:

  class HasIf a where
ifThenElse :: Bool - a - a - a
 
  instance HasIf Bool where
ifThenElse i t e = (i  t) || (not i  e)

 With `--dump-tc`, I see

  TYPE SIGNATURES
  TYPE CONSTRUCTORS
HasIf :: * - Constraint
class HasIf a
  Roles: [nominal]
  RecFlag NonRecursive
  ifThenElse :: Bool - a - a - a
  COERCION AXIOMS
axiom Main.NTCo:HasIf :: HasIf a = Bool - a - a - a
  INSTANCES
instance HasIf Bool -- Defined at ../test/HasIf.hs:4:10

 Do I need to convert the nominal coercion I got from GHC
 (`Simple.NTCo:HasIf[0] GHC.Types.Bool_N` in this case) to a
 representational one? If so, how?
 My current formulation (tweaked to use `mkSubCo` and `mkAppCo`) is to
 apply `mkAppCo (mkSubCo (Refl Nominal ep))` to the given coercion, which
 then produces

  (LambdaCCC.Lambda.EP (Sym (Simple.NTCo:HasIf[0] GHC.Types.Bool_N)))_R

 And still I get Role incompatibility: expected nominal, got
 representational in `Sym (Simple.NTCo:HasIf[0] GHC.Types.Bool_N)`.

 I also tried wrapping `mkSubCo` around the entire coercion (applying