genFFI :: HSStruct -> String
genFFI (HSStruct name types) = concat [new_lines, fields_line, offsets_lines, size_line, alignment] 
    where new_lines     = case length types of
              0 -> new_fn 0 []
              1 -> new_fn 0 $ head types
              n -> concat $ zipWith new_fn [1..] types
          new_fn ix tps = concat [beginning, "new", name, s_ix ix," :: ", arguments tps,"\n"]
          types'    tps = map (\(t,b) -> if b then t else "Ptr " ++ t) tps
          arguments tps = concat [concat (intersperse " -> " (types' tps ++ ["IO (Ptr "++ name++ ")"]))]  
          fields_line = concat [beginning, "checkFields" ,name, " :: Ptr ", name, " -> Ptr ",name, " -> IO Int8\n"] 
          offsets_lines = case length types of
              0 -> offsets_un
              1 -> offsets_un
              n -> concat $ offsets_un:map offsets_fn [1..length types]
          offsets_un    = concat [beginning, "checkOffsets",name, " :: Ptr Int16 -> IO Int8\n"] 
          offsets_fn ix = concat [beginning, "checkOffsets",name, s_ix ix, " :: Ptr Int16 -> IO Int8\n"] 
          size_line   = concat [beginning, "getSize"     ,name, " :: IO Int16\n"] 
          alignment   = concat [beginning, "getAlignment",name, " :: IO Int16\n\n"]
          beginning   = "foreign import ccall "
genFFI :: HSStruct -> String
genFFI (HSStruct name types) = concat [new_lines, fields_line, offsets_lines, size_line, alignment] 
    where new_lines     = case length types of
              0 -> new_fn 0 []
              1 -> new_fn 0 $ head types
              n -> concat $ zipWith new_fn [1..] types
          new_fn ix tps = concat [beginning, "new", name, s_ix ix," :: ", arguments tps,"\n"]
          types'    tps = map (\(t,b) -> if b then t else "Ptr " ++ t) tps
          arguments tps = concat [concat (intersperse " -> " (types' tps ++ ["IO (Ptr "++ name++ ")"]))]  
          fields_line = concat [beginning, "checkFields" ,name, " :: Ptr ", name, " -> Ptr ",name, " -> IO Int8\n"] 
          offsets_lines = case length types of
              0 -> offsets_un
              1 -> offsets_un
              n -> concat $ offsets_un:map offsets_fn [1..length types]
          offsets_un    = concat [beginning, "checkOffsets",name, " :: Ptr Int16 -> IO Int8\n"] 
          offsets_fn ix = concat [beginning, "checkOffsets",name, s_ix ix, " :: Ptr Int16 -> IO Int8\n"] 
          size_line   = concat [beginning, "getSize"     ,name, " :: IO Int16\n"] 
          alignment   = concat [beginning, "getAlignment",name, " :: IO Int16\n\n"]
          beginning   = "foreign import ccall "
genFFI (HSStruct name types) = concat [new_lines, fields_line, offsets_lines, size_line, alignment] 
    where new_lines     = case length types of
              0 -> new_fn 0 []
              1 -> new_fn 0 $ head types
              n -> concat $ zipWith new_fn [1..] types
          new_fn ix tps = concat [beginning, "new", name, s_ix ix," :: ", arguments tps,"\n"]
          types'    tps = map (\(t,b) -> if b then t else "Ptr " ++ t) tps
          arguments tps = concat [concat (intersperse " -> " (types' tps ++ ["IO (Ptr "++ name++ ")"]))]  
          fields_line = concat [beginning, "checkFields" ,name, " :: Ptr ", name, " -> Ptr ",name, " -> IO Int8\n"] 
          offsets_lines = case length types of
              0 -> offsets_un
              1 -> offsets_un
              n -> concat $ offsets_un:map offsets_fn [1..length types]
          offsets_un    = concat [beginning, "checkOffsets",name, " :: Ptr Int16 -> IO Int8\n"] 
          offsets_fn ix = concat [beginning, "checkOffsets",name, s_ix ix, " :: Ptr Int16 -> IO Int8\n"] 
          size_line   = concat [beginning, "getSize"     ,name, " :: IO Int16\n"] 
          alignment   = concat [beginning, "getAlignment",name, " :: IO Int16\n\n"]
          beginning   = "foreign import ccall "