Haskell: Как присоединиться к естественной трансформации?
Я могу определить естественное преобразование в Haskell как:
h :: [a] -> Maybe a
h [] = Nothing
h (x:_) = Just x
и с функцией k:
k :: Char -> Int
k = ord
Условие естественности соблюдено в связи с тем, что:
h . fmap k
== fmap k . h
Может ли условие естественности списка монады join
Функция будет продемонстрирована аналогичным образом? У меня возникли проблемы с пониманием, как join
, сказать concat
в частности, это естественная трансформация.
1 ответ
Хорошо, давайте посмотрим на concat
,
Во-первых, вот реализация:
concat :: [[a]] -> [a]
concat = foldr (++) []
Это соответствует структуре вашего h
где Maybe
заменяется []
и, что более важно, []
заменяется на - злоупотреблять синтаксисом на мгновение--[[]]
,
[[]]
это тоже функтор, конечно, но это не Functor
пример того, как его использует условие естественности. Перевод вашего примера напрямую не сработает:
concat . fmap k
= / = fmap k . concat
... потому что оба fmap
S работают только на самом внешнем []
,
И хотя [[]]
гипотетически является действительным примером Functor
Вы не можете сделать это напрямую, по практическим причинам, которые, вероятно, очевидны.
Тем не менее, вы можете восстановить правильный подъем следующим образом:
concat . (fmap . fmap) k
== fmap k . concat
...где fmap . fmap
эквивалентно реализации fmap
для гипотетического Functor
экземпляр для [[]]
,
В качестве связанного дополнения, return
неловко по противоположной причине: a -> f a
является естественным преобразованием из функтора элидируемой идентичности. С помощью : []
личность будет написана так:
(:[]) . ($) k
== fmap k . (:[])
... где совершенно лишнее ($)
стоит за то, что будет fmap
над элитным функтором идентичности.