как мне войти в систему на haskell?

<p>я пытаюсь использовать hslogger, чтобы получить некоторую информацию о моей программе. поэтому я добавляю следующую строку в мою функцию </p><pre><code>import data.word import qualified data.bytestring as b import qualified data.bytestring.lazy as l import data.bits import data.int import data.bytestring.parser import system.log.logger import system.log.handler.syslog importfile :: filepath -> io (either string (pesfile )) importfile n = do warningm "myapp.component2" "something bad is about to happen." ... </code></pre><p>и это прекрасно работает, потому что функция внутри io. однако, когда я добавляю похожую строку в следующую функцию:</p><pre><code>... parsepes :: parser pesfile parsepes = do header <- string "#pes" warningm "parsing header" ... return (pesfile ...) </code></pre><p>я получаю ошибку типа: </p><pre><code> couldn't match expected type `parser a0' with actual type `string -> io ()' in the return type of a call of `warningm' in a stmt of a 'do' expression: warningm "parsing header" in the expression: do { header <- string "#pes"; warningm "parsing header"; ... </code></pre><p>и я полностью понимаю, почему - parsepes находится в монаде parser, а не в монаде io . я не понимаю, что с этим делать. нужен ли мне преобразователь монад, чтобы я мог сложить монаду parser и монаду io вместе? как мне это сделать?</p>

<p>во-первых, быстрый отказ от ответственности: «регистрация» обычно не имеет смысла в общем коде на haskell, поскольку предполагает некоторое своего рода последовательное выполнение, которое может иметь или не иметь смысл. убедитесь, что вы различаете <em>ведение журнала выполнения программы</em> и <em>ведение журнала того, какие значения вычислены</em>. в строгих императивных языках они в основном одинаковы, но в хаскеле это не так.</p><p>тем не менее, звучит так, как будто вы хотите вести журнал на основе вычисляемых значений в контексте уже последовательных вычислений и вычислений с учетом состояния, что в значительной степени работает так же, как ведение журнала в большинстве других языков. тем не менее, вам нужна монада для поддержки некоторых средств для этого. похоже, что используемый вами синтаксический анализатор - <a href="http://hackage.haskell.org/packages/archive/hcodecs/0.2/doc/html/data-bytestring-parser.html">из пакета hcodecs</a> , который выглядит относительно ограниченным, не допускает <code>io</code> и не определяется как преобразователь монад.</p><p>честно говоря, мой совет - рассмотреть возможность использования другой библиотеки разбора. <a href="http://hackage.haskell.org/package/parsec">parsec</a> имеет тенденцию быть своего рода выбором по умолчанию, и я думаю, что <a href="http://hackage.haskell.org/package/attoparsec">attoparsec</a> популярен для определенных целей (которые могут включать в себя то, что вы делаете). любой из них позволил бы добавлять журналирование гораздо проще: parsec - это монадный преобразователь, поэтому вы можете поместить его поверх <code>io</code>, а затем использовать <code>liftio</code> по мере необходимости, тогда как attoparsec разработан для инкрементной обработки, так что вы можете разделить входные и логические аспекты обработка (хотя регистрация внутри фактического парсера может быть более неудобной). есть и другие варианты, но я не знаю достаточно деталей, чтобы дать рекомендацию. большинство библиотек, основанных на комбинаторе синтаксических анализаторов, имеют довольно схожий дизайн, поэтому я ожидаю, что перенос вашего кода будет простым.</p><p>последний вариант, если вы <em>действительно</em> хотите придерживаться того, что у вас есть, - это посмотреть на реализацию используемой вами библиотеки синтаксического анализа и развернуть свою собственную <code>io</code>-ориентированную версию. но это, вероятно, не идеально.</p><hr><p>кроме того, в качестве дополнения, если вы, что вы действительно ищете, на самом деле не регистрируют, а просто отслеживают выполнение вашей программы как часть разработки, вы можете найти отладчик, встроенный в ghci, более полезным или старомодным. отладка printf через <a href="http://hackage.haskell.org/packages/archive/base/4.3.1.0/doc/html/debug-trace.html">модуль debug.trace</a> .</p><hr><p><strong>edit</strong>: хорошо, звучит так, будто у вас есть правдоподобные причины подумать о том, чтобы применить свой вариант. здесь вы примерно хотите получить преобразователь монад <code>parsert</code>. вот текущее определение <code>parser</code>:</p><pre><code>newtype parser a = parser { unparser :: s -> either string (a, s) } </code></pre><p>тип <code>s</code> - это состояние анализатора. обратите внимание, что это примерно жестко закодированная версия <code>statet s (either string) a</code>:</p><pre><code>newtype statet s m a = statet { runstatet :: s -> m (a,s) } </code></pre><p>... где <code>either string</code> рассматривается как монада ошибок. преобразователь <code>errort</code> делает то же самое:</p><pre><code>newtype errort e m a = errort { runerrort :: m (either e a) } </code></pre><p>таким образом, если текущий тип эквивалентен <code>statet s (errort string identity)</code>, то, что вы хотите, будет <code>statet s (errort string io)</code>.</p><p>похоже, что большинство функций в модуле не связываются с внутренностями монады <code>parser</code>, поэтому вы <em>должны</em> иметь возможность просто заменить определения типов, предоставить соответствующие экземпляры классов типов, написать свою собственную функцию <code>runparser</code> и будь хорошим.</p>

<p>отказ от ответственности: я являюсь автором <a href="http://hackage.haskell.org/package/logger-0.1.0.0">каркаса logke haskell</a> .</p><p>хотя ответ макканна очень подробный, он не говорит о том, что на момент, когда был задан вопрос, у хаскелла не было каркаса ведения журнала общего назначения. hslogger теперь является стандартом, но он обеспечивает базовые функции ведения журналов, хотя и медленный, но не расширяемый. для ясности, вот некоторые недостатки hslogger:</p><ol> <li>это медленно. под медлительностью я подразумеваю, что каждый раз, когда вы регистрируете сообщение, оно анализирует (очень простым способом) строку, описывающую происхождение журнала, и использует некоторые экзистенциальные типы данных под капотом, которые должны вводить некоторые издержки производительности во время выполнения. ,.</li> <li>он не позволяет входить в другие монады, кроме io, поэтому вы должны использовать <code>writert</code> или другие решения, чтобы не испортить ваш код.</li> <li>он не расширяемый - вы не можете создавать свои собственные уровни приоритетов, определять пользовательское поведение (например, ведение журнала между потоками) или фильтровать журналы времени компиляции.</li> <li>он не предоставляет некоторую информацию, такую как номера строк или имена файлов, в которые были помещены журналы. и, конечно, очень сложно расширить его для поддержки такой информации.</li> </ol><p>при этом я хотел бы представить <a href="http://hackage.haskell.org/package/logger-0.1.0.0">каркас логгера haskell</a> . это позволяет для эффективной и расширяемой регистрации, в том числе:</p><ol> <li>регистрация в последовательном чистом коде (выполнение, а также использование <code>writert</code> монады)</li> <li>расширенная фильтрация сообщений (включая фильтрацию во время компиляции)</li> <li>возможность регистрации между потоками</li> <li>предоставляет интерфейс <code>templatehaskell</code>, позволяющий регистрировать дополнительные детали, такие как номера файлов или имена модулей</li> <li>очень легко расширяемый - все функции создаются как расширения простого <code>baselogger</code>, который не может сделать ничего разумного. чтобы быть ясным - функциональность фильтрации создается менее чем за 20 строк в виде логгера-преобразователя, и вы можете определить свои собственные преобразователи. как это сделать описано в <a href="https://github.com/wdanilo/haskell-logger">документации</a> .</li> <li>по умолчанию обеспечивает цветной вывод на всех платформах.</li> </ol><p>но библиотека довольно новая, поэтому ей может не хватать необходимой функциональности. хорошая информация заключается в том, что вы можете легко создать эту функцию самостоятельно или помочь нам улучшить ее, отправив запрос на github.</p><p>регистратор разработан внутри компании, в которой я работаю ( <a href="http://luna-lang.org">luna-lang.org</a> ), и используется внутри компилятора, который мы создаем. </p>

<p>бесстыдный плагин: я являюсь автором библиотеки журналов <code>co-log</code>. вы можете найти подробную информацию об использовании и реализации библиотеки в следующем сообщении в блоге:</p><ul> <li> <a href="https://kowainik.github.io/posts/2018-09-25-co-log">co-log: composable contravariant combinatorial comonadic конфигурируемая удобная регистрация</a> </li> </ul><p>основная идея этой библиотеки состоит в том, чтобы рассматривать действия по протоколированию как простую функцию haskell. так как в хаскеле работают первоклассные граждане, с ними очень легко работать.</p>