<div dir="auto">Wow, that's a useful bit of information. Thank you!</div><br><div class="gmail_quote"><div dir="ltr">On Sun, Dec 2, 2018, 3:22 PM GHC <<a href="mailto:ghc-devs@haskell.org">ghc-devs@haskell.org</a> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">#15777: Ordering of code in file affects compilation<br>
-------------------------------------+-------------------------------------<br>
Reporter: chessai | Owner: (none)<br>
Type: bug | Status: closed<br>
Priority: normal | Milestone: 8.6.2<br>
Component: Compiler | Version: 8.6.1<br>
Resolution: duplicate | Keywords:<br>
Operating System: Unknown/Multiple | Architecture:<br>
Type of failure: GHC rejects | Unknown/Multiple<br>
valid program | Test Case:<br>
Blocked By: | Blocking:<br>
Related Tickets: #12088 | Differential Rev(s):<br>
Wiki Page: |<br>
-------------------------------------+-------------------------------------<br>
<br>
Comment (by RyanGlScott):<br>
<br>
One other trick worth noting (that I learned recently from #15561) is that<br>
open and closed type families behave differently in SCC analysis, so<br>
turning `Rep` into a closed type family actually makes this typecheck.<br>
That is to say, the following compiles:<br>
<br>
{{{#!hs<br>
{-# LANGUAGE MagicHash #-}<br>
{-# LANGUAGE UnboxedTuples #-}<br>
{-# LANGUAGE TypeFamilies #-}<br>
{-# LANGUAGE TypeInType #-}<br>
<br>
-- | Conversion between unlifted and lifted datatypes<br>
module Packed.Levity<br>
( -- * Types<br>
Rep<br>
, Levity(..)<br>
) where<br>
<br>
import Data.Kind (Type)<br>
import GHC.Types (TYPE, RuntimeRep(..), Int(..), Word(..))<br>
import GHC.Exts (Int#, Word#, ByteArray#)<br>
<br>
class Levity (a :: Type) where<br>
type Unlifted a :: TYPE (Rep a)<br>
box :: Unlifted a -> a<br>
unbox :: a -> Unlifted a<br>
<br>
instance Levity Int where<br>
type Unlifted Int = Int#<br>
box = I#<br>
unbox (I# i) = i<br>
<br>
instance Levity Word where<br>
type Unlifted Word = Word#<br>
box = W#<br>
unbox (W# w) = w<br>
<br>
instance Levity Stuff where<br>
type Unlifted Stuff = Stuff#<br>
box = stuff#<br>
unbox = unStuff#<br>
<br>
type family Rep (a :: Type) :: RuntimeRep where<br>
Rep Int = IntRep<br>
Rep Word = WordRep<br>
Rep Stuff = TupleRep '[ 'IntRep, 'IntRep ]<br>
<br>
type Stuff# = (# Int#, Int# #)<br>
<br>
data Stuff = Stuff Int# Int#<br>
<br>
stuff# :: (# Int#, Int# #) -> Stuff<br>
stuff# (# x, y #) = Stuff x y<br>
<br>
unStuff# :: Stuff -> (# Int#, Int# #)<br>
unStuff# (Stuff x y) = (# x, y #)<br>
}}}<br>
<br>
You may not be able to get away with making `Rep` a closed type family in<br>
the actual program that you're writing, but I thought I'd point it out<br>
nonetheless, since I was myself unaware of this fact until today.<br>
<br>
-- <br>
Ticket URL: <<a href="http://ghc.haskell.org/trac/ghc/ticket/15777#comment:5" rel="noreferrer noreferrer" target="_blank">http://ghc.haskell.org/trac/ghc/ticket/15777#comment:5</a>><br>
GHC <<a href="http://www.haskell.org/ghc/" rel="noreferrer noreferrer" target="_blank">http://www.haskell.org/ghc/</a>><br>
The Glasgow Haskell Compiler<br>
</blockquote></div>