Re: [GHC] #2110: Rules to eliminate casted id's
#2110: Rules to eliminate casted id's -------------------------------------+------------------------------------ Reporter: igloo | Owner: Type: feature request | Status: new Priority: lowest | Milestone: 7.6.2 Component: Compiler | Version: 6.8.2 Resolution: | Keywords: Operating System: Unknown/Multiple | Architecture: Unknown/Multiple Type of failure: None/Unknown | Difficulty: Unknown Test Case: | Blocked By: Blocking: | Related Tickets: -------------------------------------+------------------------------------ Comment (by nomeata): I have a first working prototype, pushed to the wip/nomeata-T2110 branch. Comments how to do that properly and non-hacky are welcome. I ended up implementing the first idea, and this is what works: In the file {{{ module Test where import GHC.Exts import Unsafe.Coerce {-# RULES "map/coerce" map coerce = coerce #-} newtype Age = Age Int foo :: [Int] -> [Age] foo = map Age bar :: [Int] -> [Age] bar = map coerce baz :: [Int] -> [Age] baz = map unsafeCoerce }}} the rule will be desugared to {{{ ------ Local rules for imported ids -------- "map/coerce" [ALWAYS] forall (@ a_aET) (@ b_aEU) ($dCoercible_aEO :: a_aET GHC.Prim.~R# b_aEU). GHC.Base.map @ a_aET @ b_aEU ((\ (tpl_B1 :: a_aET) -> tpl_B1) `cast` (<a_aET>_R -> ($dCoercible_aEO) :: (a_aET -> a_aET) ~# (a_aET -> b_aEU))) = GHC.Prim.coerce @ [a_aET] @ [b_aEU] (GHC.Types.MkCoercible @ [a_aET] @ [b_aEU] @~ [($dCoercible_aEO)]_R) }}} and this indeed matches all three calls to `map`: {{{ Test.bar1 :: [GHC.Types.Int] -> [GHC.Types.Int] Test.bar1 = \ (tpl_B2 :: [GHC.Types.Int]) -> tpl_B2 Test.foo :: [GHC.Types.Int] -> [Test.Age] Test.foo = Test.bar1 `cast` (<[GHC.Types.Int]>_R -> [Sym Test.NTCo:Age[0]]_R :: ([GHC.Types.Int] -> [GHC.Types.Int]) ~# ([GHC.Types.Int] -> [Test.Age])) Test.bar :: [GHC.Types.Int] -> [Test.Age] Test.bar = Test.bar1 `cast` (<[GHC.Types.Int]>_R -> [Sym Test.NTCo:Age[0]]_R :: ([GHC.Types.Int] -> [GHC.Types.Int]) ~# ([GHC.Types.Int] -> [Test.Age])) }}} It does not work yet for `unsafeCoerce`, as for some reason that function is not unfolded: {{{ Test.baz = GHC.Base.map @ GHC.Types.Int @ Test.Age ((Unsafe.Coerce.unsafeCoerce1 @ GHC.Types.Int @ Test.Age) `cast` (<GHC.Types.Int>_R -> UnivCo R GHC.Types.Int Test.Age :: (GHC.Types.Int -> GHC.Types.Int) ~# (GHC.Types.Int -> Test.Age))) }}} but if it were, it would work as well :-) I find this is quite a nice result so far, the user-facing part is slick and simple, and it shows that the `Coercible` design is at least usable. Should this direction be further pursued? (PS: Special-casing `coerce` in `Rules.match` is difficult, as `Rules` is a very basic module, imported for example in `MkId` which defines `coerceId`.) -- Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/2110#comment:38> GHC <http://www.haskell.org/ghc/> The Glasgow Haskell Compiler
participants (1)
-
GHC