https://nek0.eu/posts/2016-04-19-Interfacing-variadic-functions-from-Haskell.html
Признаюсь, я поклонник Хаскелла. Всякий раз, когда я программирую что-то для удовольствия, я обычно предпочитаю этот язык из-за его элегантности.
В настоящее время я работаю над привязками Haskell к библиотеке GEGL. Мотивация этого - мое желание заниматься разработкой игр, и мне нужна библиотека для рисования на поверхностях SDL. Я, очевидно, не очень люблю простые решения и стараюсь учиться чему-то новому. Как и использование Haskell FFI.
Во время написания привязок я столкнулся с проблемой, что GEGL предоставляет в своем заголовке переменные функции, которые мне нужно связать. Это создает серьезную проблему для Haskell, потому что число аргументов функции должно быть постоянным. Просто невозможно определить функцию, не зная, сколько у нее аргументов и какого типа у каждого аргумента. Это остается верным даже для моего решения. Единственная причина, по которой мое решение работает, заключается в том, что я могу ограничить случаи, когда интерфейс этих функций варьируется до приемлемого уровня.
Для построения моих привязок я не использую стандартную FFI Haskell, а библиотеку Haskell inline-c для непосредственного вызова функций C без использования жестких привязок. Это достигается в inline-c путем помещения вызова функции в QuasiQuoter. Как я уже говорил ранее, для этого по-прежнему требуется писать QuasiQuoter для каждого случая, когда вызывается эта функция, но вам не нужно загромождать свой код объявлениями зарубежного импорта ccall.
Для ограничения ваших дел я рекомендую использовать тип суммы в качестве аргумента функции. Тип суммы - это тип, который имеет несколько конструкторов. У вас может быть конструктор для каждого случая, который вам необходим для взаимодействия и различения между ними с помощью сопоставления с шаблоном Haskell. Вы можете увидеть пример того, как сделать все это в моих привязках .