• Haskell ffi Вот есть у меня биндинги к некоей С++ либе. Из-за строк, указателей и состояния библиотеки в сигнатурах появляется IO. Настоящего I/O нет, поэтому хочется всё завернуть в свою не-IO монаду, которая сделает unsafePerformIO и обеспечит правильную последовательность вызовов посредством Reader или State. Гугл говорит, что подход не уникален и я не одинок: stackoverflow.com Но как-то настораживает отсутствие комментариев к ответу, который дал сам же спросивший. У кого-нибудь есть мысли?
    ♡ recommended by @ndtimofeev, @a2TH5, @juick

Replies (8)

  • @khorser, А через ForeignPtr не получится избавиться от какого-либо состояния вообще?
    hackage.haskell.org
  • @khorser, Ну… Во-первых там вроде бы объясняли, что подобные вещи требуют осторожности. IO это не только ввод-вывод. Если твой крестовый код занимается только тем что алоцирует память в куче и ковыряется в ней, то это одно. Если он использует некие глобальные состояния или системные вызовы — совсем другое. Кроме того побег из IO может привести к тому, что вместо того чтобы вызвать функцию два раза в одном замыкании ghc пошарит её результат. Если ты уверен, что ни это обстоятельство, ни конкурентность не сломают тебе код, то почему бы и нет?
  • @khorser, Во-вторых что мешает тебе просто написать то что хочешь и не маятся угрызениями совести? Haskell язык общего назначения. Написал? Работает? Колено цело? Самого блевать не тянет? Ну так и хрен с ним, делай коммит.
  • @khorser, По-моему, стоит либо оставить в I/O, если в либе есть таки скрытое состояние, либо заюзать ForeignPtr с файнолайзерами, если состояний нету.
    Либо поверх нечистого кода реализовать чистую обертку с ограниченным только нужным функционалом. Возможно, частично на Си.
  • @ndtimofeev, Страшно неведомых багов. Вот выдерну я всё из ИО, а х-ль возьмёт и воткнёт ленивости, где не надо, и нарушит мне последовательность вызовов. А обратно проситься в уютненькую ИО стыдно будет =)
  • @waterlaz, Состояние есть, но я его легко восстановлю одним вызовом при выходе из своей монадки. От х-ле мне нужна гарантия последовательность вызов. В ForeignPtr у меня уже завёрнуты плюсовые объекты, но не хочется заставлять пользователей лезть в ИО, когда настоящего ИО и не происходит.
  • @khorser, Внутри unsafePerformIO вызовы останутся в нужном порядке. Но есть шанс что компилятор пошарит вычисления.
  • @ndtimofeev, С внешним миром оно не общается, конкурентность — чувствительная тема и для самой либы, лишний повод задуматься, как бы её организовать ;) Из монады будет торчать runMySuperMonad :: MySuperMonad a -> a, на выходе он будет восстанавливать состояние...
    Чёрт, только сейчас понял, что ничто не запрещает вернуть из одного runMySuperMonad библиотечный объект и скормить его в другой run. Блин, неужели придётся свой ST сооружать...