deniok: (Рыжий)
deniok ([personal profile] deniok) wrote2015-11-05 10:33 pm

Экспоненциальное офункторивание

Как вам скорее всего известно, написать представителя класса типов Functor для типа эндоморфизма невозможно. Если неизвестно, то можете попробовать
newtype Endo a = Endo (a -> a)

instance Functor Endo where
   fmap f (Endo g) = Endo undefined
Даже если ваш результат сойдется по типам, законам для функтора он удовлетворять не будет.

Вот вам другой экспоненциальный тип данных, для которого, однако, написать законного представителя класса типов Functor можно:
newtype Quest b a = Quest ((a -> b) -> a)

instance Functor (Quest b) where
  fmap f (Quest g) = Quest undefined
Попробуйте сделать это, после чего ответьте на вопрос: чему равен результат такого вызова
> let Quest f = fmap succ $ Quest (\h -> h 40) in f id

[identity profile] thedeemon.livejournal.com 2015-11-06 04:14 am (UTC)(link)
42
https://gist.github.com/thedeemon/ddf63573f089dff61aae
Просто по типам разворачиваешь, не думая.

[identity profile] deni-ok.livejournal.com 2015-11-06 11:36 am (UTC)(link)
А если напустить на эту лямбду pointfree (связав предварительно еще и переменные, которые слева от равенства - как бы снимая упаковку/распаковку в newtype), то оказывается, что этот fmap - очень симметричный liftM в примитивном ридере.