<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>