Я пытаюсь понять концепцию comonads, и после прочтения этого сообщения в блоге, я думаю, что у меня есть четкое понимание того, что они делают и как они связанные с монадами. Но я подумал, что немного углубился бы в тему и подумал бы о том, как будет выглядеть экземпляр comonad типа универсального списка (вы знаете, [a]), и я пришел к тому, что я не полностью известно, что это правильно.
Итак, учитывая пример использования блога:
class Functor w => Comonad w where
(=>>) :: w a -> (w a -> b) -> w b
coreturn :: w a -> a
cojoin :: w a -> w (w a)
Я думал, что объявление экземпляра для [a] будет выглядеть примерно так (синтаксис для [a], вероятно, невозможен или неверен, но вы получаете эту идею здесь):
instance Comonad [a] where
coreturn = head
cojoin = Data.List.subsequences --this is what I'm confused about
x =>> f = map f (cojoin x)
Здесь мы просто находим все subsequences списка, но вполне возможно просто использовать его powerset или что-то еще. В списках формы (a -> [a]) есть несколько функций, и это несколько неоднозначно относительно того, какой из них правильный.
Означает ли это, что [a] не может быть правильно правильно создан как comonad, или просто для пользователя решить, что действительно будет делать cojoin?