Haskell Language
Przepisz reguły (GHC)
Szukaj…
Korzystanie z reguł przepisywania dotyczących przeciążonych funkcji
W tym pytaniu @Viclib zapytał o użycie reguł przepisywania w celu wykorzystania praw klas typowych w celu wyeliminowania niektórych przeciążonych wywołań funkcji:
Pamiętaj o następującej klasie:
class ListIsomorphic l where toList :: l a -> [a] fromList :: [a] -> l a
Żądam również tego do
toList . fromList == id
. Jak napisać reguły przepisywania, aby poinformować GHC o dokonaniu tej zamiany?
Jest to dość trudny przypadek użycia mechanizmu przepisywania reguł przez GHC, ponieważ przeciążone funkcje są przepisywane na metody ich określonych instancji za pomocą reguł, które są domyślnie tworzone za sceną przez GHC (więc coś takiego jak fromList :: Seq a -> [a]
byłoby przepisany do Seq$fromList
itp.).
Jednak najpierw przepisując toList
i fromList
w nieliniowe metody nietypowe, możemy zabezpieczyć je przed przedwczesnym przepisywaniem i zachować je do momentu uruchomienia reguły kompozycji:
{-# 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