• ? Haskell zipper А прикрутить к зипперу continuation чтобы запилить Applicative, Alternative и Monad интерфейсы для перемещения по дереву, это как, нормально или всё-таки перебор?

Replies (16)

  • @Macil, Чего ты в конце-то добиться хочешь?
  • @rkit, XML парсер с блекдже..., в смысле с FCNS закодированным деревом и интерфейсом Alternative/Applicative как у текстовых парсеров (<$>, <>, <, *>, <|>, some, many).
  • @Macil, Тогда зиппер перебором будет. Он для изменений нужен, а не просто для чтения.
  • @rkit, Зиппер-то как раз перебором не будет, т.к. нужно фокусироваться на текущем узле. Кроме того, зиппер — настолько простая штука, что перебором он никогда не бывает.
  • @Macil, Для фокуса на узле достаточно написать let x = узел. А зипперов ты не понимаешь, по-моему. Они вносят приличную вычислительную нагрузку.
  • @rkit, Тогда хрен ты прикрутишь аппликативный интерфейс...
  • @Macil, Чего-то у тебя вообще все голове смешалось, по-моему.
  • @rkit, Ах, да, и на вычислительную нагрузку мне срать...
  • @Macil, я к сожалению не очень понял вопрос, т.е. видимо у тебя что-то вроде `Zipper a = (Info-about-structure, zipCont Structure -> a)`?
    и на основе этого ты хочешь строить сложные zipper-ы используя тайпклассы Applicative, Alternative, Monad. Я не очень понимаю как это будет работать (это не значит, что то, что предложено плохо), просто я не вижу всей ситуации.
  • @qnikst, Представь себе самый обычный комбинаторный парсер типа attoparsec или парсера из aeson/binary/cereal. Они определены в continuation-форме Input -> Failure -> Success -> Result, где Failure и Success — функции в форме Input -> ... -> Result (упрощенно).
    Обычно в качестве Input применяется список или какой-нибудь stream или еще чего-нибудь что позволяет эффективно взять «слеудющий» токен и вернуть «остаток».
    Я же хочу в качесте Input использовать Zipper, т.е. можно будет написать left > right > right что будет равно композиции соответствующих операций для зиппера... Т.е. можно спокойно таскаться по дереву туда-сюда ради своих целей.
    Поскольку XML-дерево будет задано в FCNS-форме, то навигация будет достаточно специфичной, но передельно простой и главное интуитивно понятной.
    Строго говоря, для такого парсера даже не нужно идти «вверх», но мне всё-равно нужно фокусироваться на конкретном XML-узле, так что зиппер в любом случае будет.
    Вот собственно, вопрос, а стоит ли это вообще затевать... Например, Э. Кметт в своём пакете Control.Zippers (Control.Zipper, убранный из пакета lens) предлагает несколько иной подход.
  • @Macil, В пакете zippers, конечно же.
  • @Macil, смотри, я zipper это бегалка по структуре + набор функций, соотвественно все перемещение это их композиция, типа

    ```
    zipper structure & left
    & right
    & delete
    & insert 17
    & commit
    ```

    здесь мы написали большую композицию фунций где мы создаем зиппер идём влево, вправо, удаляем ноду, вставляем на её место другую и коммитим получившуюся структуру.
    Вроде все просто и наглядно.

    при этом (я так сходу не умею) если таскаться с каком-нибудь Funtor/Applicative как делается в линзах, о ещё и благодаря эффектам можно протащить аккумулятор например.
  • @qnikst, я правильно понимаю?
  • @Macil, В парсере зиппер не используется, используется чистый список. И тебе достаточно чистого дерева.
  • @qnikst, Вот вот. И не столько аккумулятор, сколько возможность «фейлить» и комбинатор <|> для работы с фейлами, плюс возможность использовать аппликативный стиль
    ```
    <Foo a="a" b="b">
    <Bar>Bar</Bar>
    </Foo>
    ```
    ```
    Foo <$> (tag "Foo" *> attribute "a")
    <*> (attribute "b")
    <> (left > tag "Bar" > left > text < upleft < upleft)
    ```
    Точную семантику комбинаторов пока определить сложно, так что написал с неспрятанной внутрь навигацией по дереву.
    Если говорить языком mtl, то это комбинация ExceptT и StateT. State протаскивает зиппер через комбинаторы, а ExceptT управляет управляет вычислимостью «следующего» комбинатора.
  • @Macil, я подозреваю, что это все можно выразить как

    Zipper f s = Zipper { f (Focus s), Context s }

    но не уверен.