Sök…


Använda omskrivningsregler för överbelastade funktioner

I den här frågan frågade @Viclib om att använda omskrivningsregler för att utnyttja typkategorilagar för att eliminera vissa överbelastade funktionssamtal:

Tänk på följande klass:

class ListIsomorphic l where
    toList    :: l a -> [a]
    fromList  :: [a] -> l a

Jag kräver också att toList . fromList == id . Hur skriver jag omskrivningsregler för att säga att GHC ska ersätta den?

Detta är ett något knepigt användningsfall för GHC: s omskrivningsregleringsmekanism, eftersom överbelastade funktioner skrivs om till sina specifika instansmetoder med regler som implicit skapas bakom kulisserna av GHC (så något liknande fromList :: Seq a -> [a] skulle vara omskrivna till Seq$fromList etc.).

Men genom att först skriva om toList och fromList till icke-inline-metoder som inte är typklass kan vi skydda dem från för tidigt omskrivning och bevara dem tills regeln för kompositionen kan avfyras:

{-# RULES
  "protect toList"   toList = toList';
  "protect fromList" fromList = fromList';
  "fromList/toList"  forall x . fromList' (toList' x) = x; #-}

{-# NOINLINE [0] fromList' #-}
fromList' :: (ListIsomorphic l) => [a] -> l a
fromList' = fromList

{-# NOINLINE [0] toList' #-}
toList' :: (ListIsomorphic l) => l a -> [a]
toList' = toList


Modified text is an extract of the original Stack Overflow Documentation
Licensierat under CC BY-SA 3.0
Inte anslutet till Stack Overflow