Haskell Language
Omskrivningsregler (GHC)
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