просветить
Dec. 28th, 2012 10:31 pmhttp://www.iai.uni-bonn.de/~jv/mpc08.pdf
ммм.... почему abs m тут можно подставить? Я думал, что forall m. TreeLike m => m a разрешает любое TreeLike m (тогда abs m is too specific и его нельзя, да?), но такое объявление функции выходит не эквивалентно improve :: TreeLike m => m a -> Tree a.
(abs - это в статье новая функция)
(про экзистенциальные типы читал, но в чём тут трюк не пойму)
порешал. TreeLike m => m a говорит, что функция работает с любым instance. (forall m. TreeLike m => m a) в данном случае означает, что caller обязан не выбирать конкретный instance TreeLike, т.е. caller "работает" с любым instance TreeLike, т.е. полиморфизм "навыворот". Конкретный instance выбирается на основании реализации improve.
Т.о. caller строит деревья с помощью TreeLike leaf и node - тем самым caller декларирует, что ему всё равно, какой именно instance подставить. Тогда improve = abs, выбрав CTree, заставляет caller тоже "пользоваться" leaf и node из CTree, но этот вопрос решается компилятором. Какая замечательная фича.
improve :: (forall m. TreeLike m => m a) -> Tree a improve m = abs m
(abs - это в статье новая функция)
(про экзистенциальные типы читал, но в чём тут трюк не пойму)
порешал. TreeLike m => m a говорит, что функция работает с любым instance. (forall m. TreeLike m => m a) в данном случае означает, что caller обязан не выбирать конкретный instance TreeLike, т.е. caller "работает" с любым instance TreeLike, т.е. полиморфизм "навыворот". Конкретный instance выбирается на основании реализации improve.
Т.о. caller строит деревья с помощью TreeLike leaf и node - тем самым caller декларирует, что ему всё равно, какой именно instance подставить. Тогда improve = abs, выбрав CTree, заставляет caller тоже "пользоваться" leaf и node из CTree, но этот вопрос решается компилятором. Какая замечательная фича.