haskell / c2hs

c2hs is a pre-processor for Haskell FFI bindings to C libraries
http://hackage.haskell.org/package/c2hs
Other
198 stars 50 forks source link

Support for type synonyms #147

Open mjakob opened 9 years ago

mjakob commented 9 years ago

First of all, thank you for a great pre-processor!

I recently had a use case that can be simplified to this:

-- TypeSynonyms.chs
import Foreign.C

#include <stdio.h>

{#fun fopen as ^ { `FilePath', `String' } -> `Ptr CFile' #}

If this is processed by c2hs (in my particular case v0.25.2), I get:

$ c2hs TypeSynonyms.chs
c2hs: Errors during expansion of binding hooks:

TypeSynonyms.chs:5: (column 20) [ERROR]  >>> Missing "in" marshaller!
  There is no default marshaller for this combination of Haskell and C type:
  Haskell type: FilePath
  C type      : (Ptr CChar)

This can easily be solved by adding withCString* as in marshaller to the FilePath argument (or change FilePath to String, but I like the implicit documentation it brings), but in my real case I have a lot of functions accepting FilePaths. Hence, to keep it DRY, I tried to define a default marshaller for FilePath:

{#default in `FilePath' [char *] withCString* #}

but this didn't go as well as I'd hoped:

$ c2hs TypeSynonyms.chs
c2hs: Errors during expansion of binding hooks:

TypeSynonyms.chs:6: (column 20) [ERROR]  >>> Missing "in" marshaller!
  There is no default marshaller for this combination of Haskell and C type:
  Haskell type: FilePath
  C type      : (Ptr CChar)
TypeSynonyms.chs:5: (column 3) [ERROR]  >>> Internal type default error!
  Something went wrong.

Perhaps there's already a simple solution that I have overlooked? Otherwise, I would like to make a vote for a new feature that solves this problem. Either something like my #default attempt or, in a perfect world, c2hs would see that FilePath is just a String and treat it as such.

Regards, Mattias

ian-ross commented 9 years ago

@mjakob That's interesting. I'd never really thought about the fact that C2HS chases C type aliases, but not Haskell ones!

Something like your second attempt really ought to work with the current version of C2HS, so that's definitely a bug that I'll fix. I'll have to look at the Haskell type alias chasing more carefully. I agree that this ought to just work as it is, but I don't know how tricky it would be to do it. I'll get back to you...

mjakob commented 9 years ago

Thank you for looking into this, I'll be keeping an eye out for updates!

While experimenting, I found that I can get rid of the second error, "Internal type default error!", by adding a {#typedef char CChar #} above the #default hook. The documentation hints that there should always be a #typedef preceeding a #default hook, but in this case I don't understand why. Anyhow, I thought there's a slight chance this will help in the troubleshooting.

shanemikel commented 8 years ago

This problem really bit me today..

Unfortunately I'm still trying to find a workaround. My situation involves Ptr () and a newtype wrapper around it.

Here's my chs file https://gist.github.com/shanemikel/5f79359e79680c01fb4e19a1ffecd6b4