Alexander
так?
кана
хм, ну вручную мы f не подставляем, но это делают всякие over/view за нас, правильно?
Alexander
что такое поэтому если мы говорим пользователю, что требуем от функции больше (Applicative) у нас все продолжает работать
parket
Alexander
ну да, очень плохой язык, но линза ничего не знает о типе f кроме того, что он функтор
Alexander
@banana_is ?
кана
там опечатка просто у тебя, он исправил
кана
Alexander
если твоя функция подставляет f которая Applicative, как это требует Traversable, то такая функция автоматически работает и для Lens, которому нужен только Functor
кана
Да, это понятно, если функция может работать как траверсабл, то он может работать и как линза
Cheese
Dmitry
а что?
Alexander
@jagajaga тогда уж ещё
Alexander
там вопрос про стажировки
Alexander
Alexander
если у нас есть функция работающая как линза, то она будет работать как траверсабл
Alexander
я это написал
Alexander
обратное неверно!
Serghei
мы с женой прям поржали
Serghei
про _|_
кана
черт, я же написал то же самое, что и ты в предпоследнем сообщении)
Serghei
никогда бы в голову не пришла такая аналогия
Alexander
@kana_sama давай что-нить попроще, type X a = forall Traversable f => a -> f a
кана
а это один из переводов слова bottom
Alexander
и реализация pure :: X a
Anton
кана
bottom ~ ass
Alexander
и пусть есть type Y a = forall f . Functor f => a -> f a
Alexander
pure не может быть типа Y a
Anton
ну, а ascii-art _|_ вообще в приличном обществе не переведёшь
Anton
bottom - это в общем-то не ругательство
Alexander
а теперь рассмотрим, type Z a = forall f . Functor f => f a -> f ()
кана
стой
Alexander
и fmap (const ()) :: Z a
Alexander
стою
Arseniy
кана
это из-за того, что значение справа от стрелки? Потом что будь это обычное значение, то все же ок, разве нет?
кана
и пусть есть type Y a = forall f . Functor f => a -> f a
кана
pure не может быть типа Y a
кана
а теперь рассмотрим, type Z a = forall f . Functor f => f a -> f ()
Alexander
@kana_sama да из-за этого
кана
имея некий траверсабл, мы спокойно можем отправить его туда, где нужен функтор
Alexander
да
Alexander
хочешь я полный гист сделаю
Alexander
а тот посреди обсуждения жопы всякие вылезают
кана
но имея функцию, которая отдает траверсабл, мы не можем отравить ее туда, где нужна функция, которая отдает функтор
Alexander
я не уверен, чот отдает/ждет терминология здесь точная, но направление вроде верное
кана
не, я сейчас сам поэксперементирую. У меня есть некоое понимание контрвариативности в плане работы функторов, но нет такого же понимания на тайплкассов
Alexander
{-# LANGUAGE RankNTypes #-}
type X a = forall f . Applicative f => a -> f a
type Y a = forall f . Functor f => a -> f a
p :: X a
p = pure
-- q :: Y a
-- q = p -- • Could not deduce (Applicative f) arising from a use of ‘pure’
type V a = forall f . Functor f => f a -> f ()
type W a = forall f . Applicative f => f a -> f ()
v :: V a
v = fmap (const ())
w :: W a
w = v
Alexander
полный код
кана
Благодарю. Пока не щелкнуло, но почему не работает мне понятно
кана
Так, слева от стрелки у нас негативная позиция, типы там контрвариантны. Справа положительная, там все ковариантно. f a тут именно справа...
кана
когда у нас тип
(a -> f a) -> (b -> f b)то a -> f a у нас в негативной позиции, а f a в положительной, значит f a в негативной (1 * (-1) = -1), аналогично f b в положительной. То есть у нас f сразу и в положительной позиции, и в отрицательной
кана
Интуиция мне подсказывает, что такой случай обозначает инвариант, мы не можем ни обобщить, ни специализировать, но реальность совсем не такова
Alexander
я ничего не понимаю (всегда путаюсь в ко и контр-вариантности), но что-то мне подсказывает, что разница в
Alexander
type X f = ... vs type X = forall f. ...
Alexander
и важно где тут f относительно =
Alexander
@kana_sama ^
кана
капец
Alexander
примерно так же как и с forall x . S x vs S (forall x. x)
Alexander
здесь у нас случай аналогичный S (forall x.x)
кана
нужно попробовать это как-то нарисовать
кана
ток сейчас понял, что юзер никакого f установить не может, нам же важен факт того, что этот тип работает для любых f
кана
type Traversal' a b =
forall f . Applicative f =>
(b -> f b) -> (a -> f a)
кана
type Lens' a b =
forall f . Functor f =>
(b -> f b) -> (a -> f a)
Alexander
что ты понимаешь под юзер?
Alexander
caller может
Alexander
caller собственно это и делает подставляет Const и Identity
Alexander
а линза работает для всех
кана
так, caller это кто в нашем случае?
кана
view/over/...?
Зигохистоморфный
вся магия в поведении функторов Const и Identity
fst f (a, b) = fmap (\a' -> (a', b)) (f a)
и как бы все видно что происходи смотря что передать в f (Const, Identity, (Identity . fn))
Зигохистоморфный
modifyLens f lens = runIdentity . lens (Identity . f)
Зигохистоморфный
setLens x = modifyLens (const x)
Зигохистоморфный
viewLens lens = getConst . lens Const
Зигохистоморфный
даже вместо . лучше #.
кана
Ну это таки более менее понятно, не очень понятно, как позиция класса в стрелке вляет на возможностью обобщения и специализации, и влияет ли вообще, то есть тема с линзами связана косвенно
Alexander
Vasiliy
Alexander
там не в этом же вопрос был