Haskell Language
Переписать правила (GHC)
Поиск…
Использование правил перезаписи для перегруженных функций
В этом вопросе @Viclib попросил об использовании правил перезаписи для использования законов типа typeclass для устранения некоторых перегруженных вызовов функций:
Обратите внимание на следующий класс:
class ListIsomorphic l where toList :: l a -> [a] fromList :: [a] -> l a
Я также требую, чтобы
toList . fromList == id
. Как написать правила перезаписи, чтобы сообщить GHC сделать эту замену?
Это несколько сложный вариант для механизма правил перезаписи GHC, поскольку перегруженные функции переписываются в их конкретные методы экземпляра правилами, которые неявно создаются за кулисами GHC (так что что-то вроде fromList :: Seq a -> [a]
будет переписан в Seq$fromList
и т. д.).
Однако, сначала переписывая toList
и fromList
в не-встроенные методы без класса, мы можем защитить их от преждевременного переписывания и сохранить их до тех пор, пока правило для композиции не будет срабатывать:
{-# 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