hsc2hs: мутировать структуру C с помощью Haskell

Я пытаюсь написать программу на Haskell, которая взаимодействует с C (в конечном счете, для iOS через GHC-iOS). Я хочу, чтобы он передал строку из C в Haskell, чтобы Haskell обработал ее, а затем возвратил некоторые типы данных из Haskell в C Structs через hsc2s. Мне не удалось найти ясный, простой учебник. Единственное, что нужно Haskell от C - это String, больше ничего.

У меня нет проблем с самой первой частью, передавая строку в Haskell.

testPrint :: CString -> IO ()
testPrint c = do 
    s <- peekCString c
    putStrLn s

Для целей тестирования и использования в будущем я просто хочу иметь возможность обрабатывать что-то вроде следующего.

C Struct

struct testdata {
   char *a;
   char *b;
   int c;
};

Тип данных Haskell

data TestData =  TestData {
  a :: String,
  b :: String,
  c :: Int
} deriving Show

-- not sure what the type would look like
testParse :: CString -> TestData

Я понимаю, что мне нужно типизировать TestData как Storable и реализовать peek, poke, sizeOf и выравнивание, но мне нужно увидеть простой пример, прежде чем я действительно смогу его понять. Большинство уроков требуют внешних библиотек и делают их более сложными, чем это должно быть.

Вот ресурсы, на которые я смотрел:

Stackoverflow - Как использовать hsc2hs для привязки к константам, функциям и структурам данных?

Haskell Cafe - FFI для начинающих

Написание интерфейсов Haskell для кода C: hsc2hs

Haskell Wikibook - FFI

Изменить: в настоящее время, где я застрял (получает ошибку сегментации, когда setFoo вызывается в C)

Фрагмент кода на Haskell

instance Storable Foo where
  sizeOf = #{size foo}
  alignment = alignment (undefined :: CString)
  poke p foo = do
     #{poke foo, a} p $ a foo
     #{poke foo, b} p $ b foo
     #{poke foo, c} p $ c foo
  peek p = return Foo
    `ap` (#{peek foo, a} p)
    `ap` (#{peek foo, b} p)
    `ap` (#{peek foo, c} p)

foreign export ccall "setFoo" setFoo :: Ptr Foo -> IO ()

setFoo :: Ptr Foo -> IO ()
setFoo f = do
  newA <- newCString "abc"
  newB <- newCString "def"
  poke f (Foo newA newB 123)

Фрагмент кода C

foo *f;
f = malloc(sizeof(foo));
foo->a = "bbb"
foo->b = "aaa"
foo->c = 1
// this is incorrect
// setFoo(&f);
// this is correct
setFoo(f);

Ответы на вопрос(1)

Ваш ответ на вопрос