Поиск…


Использование правил перезаписи для перегруженных функций

В этом вопросе @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


Modified text is an extract of the original Stack Overflow Documentation
Лицензировано согласно CC BY-SA 3.0
Не связан с Stack Overflow