Расширения классов типов. Конспект.
Jul. 29th, 2008 03:54 pmРасширения типа fundep или MPTC обычно понятны бывают сразу, ну, по крайней мере, их идея. А вот чтобы разобраться с ошибками при инстанциировании класса, придётся разобраться.
-XConstrainedClassMethods
Позволяет определять контекст над переменными типа из объявления класса в объявлениях методов.
Частичная задача -XFlexibleContexts.
Пример
Здесь в
-XUndecidableInstances
Аналог синонимов типов. Синонимы класса. Применяется совместно с FlexibleInstances.
Пример
Экземпляр класса здесь представляет не конкретный тип, а
-XOverlappingInstances
С предыдущей опцией можно наворотить кучу инстансов, которые могут быть применимы к одному и тому же набору типов.
И вот мы применяем
При включении флага
-XIncoherentInstances
Пойдём дальше, предположим, что некой функции мы выбрали наиболее точный инстанс, однако эта функция может примениться к типу, для которого подходит ещё более точный инстанс. Код:
Здесь тип
На сегодня всё :-) Более общие вещи типа
-XConstrainedClassMethods
Позволяет определять контекст над переменными типа из объявления класса в объявлениях методов.
Частичная задача -XFlexibleContexts.
Пример
{-# LANGUAGE MultiParamTypeClasses, ConstrainedClassMethods #-}
class Map m k v where
empty :: m k v
put :: k -> v -> m k v -> m k v
get :: Eq k => k -> m k v -> Maybe v
Здесь в
get определён контекст для k.-XUndecidableInstances
Аналог синонимов типов. Синонимы класса. Применяется совместно с FlexibleInstances.
Пример
{-# LANGUAGE FlexibleInstances, UndecidableInstances #-}
class ObservableEq a where
(===) :: a -> a -> Bool
instance Eq a => ObservableEq a where
(===) = (==)
Экземпляр класса здесь представляет не конкретный тип, а
(Eq a) => a.-XOverlappingInstances
С предыдущей опцией можно наворотить кучу инстансов, которые могут быть применимы к одному и тому же набору типов.
{-# LANGUAGE FlexibleInstances, UndecidableInstances, OverlappingInstances #-}
class ObservableEq a where
(===) :: a -> a -> Bool
instance Eq a => ObservableEq a where
(===) = (==)
instance ObservableEq [a] where
(x:xs) === (y:ys) = True
_ === _ = False
И вот мы применяем
(===) к [Int]. Какой инстанс сработает?При включении флага
OverlappingInstances GHC не будет ругаться, а выберет более точный инстанс (в нашем случае последний).-XIncoherentInstances
Пойдём дальше, предположим, что некой функции мы выбрали наиболее точный инстанс, однако эта функция может примениться к типу, для которого подходит ещё более точный инстанс. Код:
{-# LANGUAGE FlexibleInstances, UndecidableInstances, OverlappingInstances, IncoherentInstances #-}
class ObservableEq a where
(===) :: a -> a -> Bool
instance Eq a => ObservableEq a where
(===) = (==)
instance ObservableEq [a] where
(===) = undefined
instance ObservableEq [Integer] where
(===) = (==)
tailsObsEq xs ys = tail xs === tail ys
Здесь тип
tailsObsEq :: (ObservableEq [a]) => [a] -> [a] -> Bool, т.е. был применён второй instance. Если мы выключим ключик IncoherentInstances, то поимеем ошибку при сравнении tailsObsEq [1] [1], т.к. это уже тип [Integer]. IncoherentInstances же закрепляет за tailsObsEq навсегда второй инстанс.На сегодня всё :-) Более общие вещи типа
FlexibleInstance ещё до тонкостей не понимаю.
no subject
Date: 2008-07-29 01:35 pm (UTC)no subject
Date: 2008-07-29 01:46 pm (UTC)FlexibleInstance afair просто упрощает ограничения на заголовок instance. стандартные ограничения сделаны довольно жёстко чтобы гарантировать децидабельность. с этим флагом используюься более гибкие ограничения, тем не менее обеспечивающие децидабельность. в частности, type sysmonyms (String вместо хСрфкъ) не этот флаг позволяет писать?
no subject
Date: 2008-07-29 03:15 pm (UTC)нет мне оправданья!
На вики добавлю, ага.
no subject
Date: 2008-07-29 01:58 pm (UTC)http://repetae.net/recent/out/supertyping.html
no subject
Date: 2008-07-29 03:18 pm (UTC)no subject
Date: 2008-07-30 05:37 am (UTC)Но до сих пор не убрал этот suggestion.
И я тоже сомневаюсь, поэтому и спрашиваю :-)
no subject
Date: 2008-07-29 03:48 pm (UTC)no subject
Date: 2008-07-30 09:31 am (UTC)Почему не в сообщество - не знаю, я в свой журнал в основном по Haskell пишу и даже не задумывался над тем, чтобы писать в лямбду (ты же про неё?)
Пока вот: http://haskell.org/haskellwiki/Ru/GHC/Class_Instance_Extensions
no subject
Date: 2008-07-29 03:57 pm (UTC)no subject
Date: 2008-07-30 09:31 am (UTC)no subject
Date: 2008-07-29 09:08 pm (UTC)no subject
Date: 2008-07-30 09:27 am (UTC)