hsc2hs: mutar una estructura C con Haskell

Estoy tratando de escribir un programa Haskell que se comunique con C (en última instancia para iOS a través de GHC-iOS). Quiero que pase una cadena de C a Haskell, haga que Haskell lo procese y luego devuelva algunos tipos de datos de Haskell a C Structs a través de hsc2s. No he podido encontrar un tutorial claro y simple. Lo único que Haskell necesita de C es la Cadena, nada más.

No tengo problemas con la primera parte, pasarle una cuerda a Haskell.

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

Para fines de prueba y referencia futura, solo quiero poder manejar algo como lo siguiente.

C estructura

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

Tipo de datos Haskell

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

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

Entiendo que necesito escribir la clase TestData como Almacenable e implementar peek, poke, sizeOf y alineación, pero necesito ver un ejemplo simple antes de que realmente pueda entenderlo. La mayoría de los tutoriales requieren bibliotecas externas y lo hacen más complicado de lo que debe ser.

Aquí están los recursos que he visto:

Stackoverflow - ¿Cómo usar hsc2hs para enlazar constantes, funciones y estructuras de datos?

Haskell Cafe: FFI para principiantes

Escribir interfaces de Haskell en código C: hsc2hs

Haskell Wikibook - FFI

Editar: actualmente donde estoy atascado (aparece un error de segmentación cuando se llama a setFoo en C)

Fragmento de código 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)

Fragmento de código 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);

Respuestas a la pregunta(1)

Su respuesta a la pregunta