[Agda] Re: Agda FFI bindings

Alan Jeffrey ajeffrey at bell-labs.com
Mon Sep 20 20:34:08 CEST 2010


Next problem... universe polymorphism.  There was already a thread on 
this "COMPILED_DATA directive for Maybe":

  http://thread.gmane.org/gmane.comp.lang.agda/1237/

One thing that's not mentioned there is that there actually is a binding 
for the universe-polymorphic Maybe type which typechecks:

  {-# COMPILED_DATA Maybe AMaybe Just Nothing #-}

where AMaybe is a Haskell type defined:

  type AMaybe a b = Maybe b

This is fine, and indeed compiles Agda Maybe into Haskell Maybe. 
Unfortunately, you can't use the type in another FFI binding, for example:

  postulate isJust : {a : Level} → {A : Set a} → (Maybe A) → Bool
  {-# COMPILED isJust isJust #-}
  // The type {a : Level} {A : Set a} → Maybe A → Bool cannot be
  // translated to a Haskell type.

For universe-monomorphic bindings you get a different error:

  postulate isJust : {A : Set zero} → (Maybe A) → Bool
  {-# COMPILED isJust isJust #-}
  // The type zero cannot be translated to a Haskell type.

The source of these errors is HaskellTypes.hs -- it looks like there'd 
be an easy fix for universe-monomorphic bindings, which is to add a 
cluase to haskellType, something like:

   Lit (LitLevel _ _) -> "()"

There's probably a similar hack for polymorphic bindings, by adding a 
case for the BUILTIN_LEVEL datatype to haskellKind.

As NAD said in the previous thread, the best bet right now is to define 
a universe-monomorphic Foreign.Haskell.Maybe type with translations back 
and forth to Data.Maybe {zero}, but boy does this result in a lot of 
ugly wrapper code.

A.

On 09/17/2010 03:30 PM, Jeffrey, Alan S A (Alan) wrote:
> OK, my first problem in FFI bindings to Haskell: what's the treatment of
> binding to recursive datatypes and functions?  (There's a matching
> problem of nonterminating computation and error, but lets ignore that
> for now.  Ditto unsoundness of postulates.)
>
> As a concrete example, take the List datatype and its append function
> (ignoring for now that Agda has its own perfectly good append function).
>
> Currently, Foreign.Haskell gives a binding for Haskell lists as Agda
> Colists, so the Agda binding for append is:
>
>     append : {X : Set} ->  (Colist X) ->  (Colist X) ->  (Colist X)
>
> This can be wrapped in a conversion function from lists to colists, but
> there's nothing we can do to convert the result back a list, without
> switching off termination checking.
>
> An alternative would be to do what Data.String does for strings, and
> bind Haskell lists to Agda Lists, which gives append the desired type:
>
>     append : {X : Set} ->  (List X) ->  (List X) ->  (List X)
>
> then it's the responsibility of the author of the library with FFI
> bindings to ensure that all such bindings maintain finiteness.
>
> Note that in both cases there's a responsibility on the author: in the
> case of bindings to coinductive types, it's to maintain guardedness, and
> in the case of bindings to inductive types, it's to maintain finiteness.
>
> We could do both, although this would probably end up with either a fair
> bit of code duplication or complex types to track inductive vs
> coinductive types.
>
> Finally, we could just say that the author is allowed whatever bindings
> they like, and is not required to maintain any invariants, but this
> sounds like a recipe for cryptic MAlonzo error messages.
>
> Having hacked out a bunch of code built on top of Haskell FFI libraries
> recently, I've found the inductive bindings to be extremely useful, and
> have yet to use any coinductive bindings.  Of course, this may say more
> about me than it does about common programming idioms :-)
>
> So my temptation is to focus on inductive, rather than coinductive
> bindings to Haskell.
>
> Thoughts?
>
> A.
>
> On 09/16/2010 02:40 PM, Jeffrey, Alan S A (Alan) wrote:
>> Dear Agda folks,
>>
>> I've been working on some Agda applications, which have made a fair bit
>> of use of the FFI to Haskell, and I thought it might make sense to
>> share.  Currently I've got simple bindings for:
>>
>> - Data.Maybe
>> - Data.ByteString.Lazy
>> - Text.XML.Expat
>> - Network.URI
>> - Data.Int.Int64
>>
>> Is there currently a home for such bindings?  If not, I'd like to start
>> one up.  If anyone else has FFI bindings to share, I'd be happy to
>> provide a home for them.
>>
>> Before I start uploading code, I'd like to ask a bit about coding style.
>>     The style I've been using so far has been to define two modules:
>>
>> - Foreign.Haskell.Foo: contains just the raw FFI bindings
>> - Foo: links against Foreign.Haskell.Foo, and provides the Agda layer.
>>
>> Is this good practice?  Or should I just include the FFI code in with
>> the Agda library?
>>
>> There are many gory questions about the particular FFIs, but I'll put
>> those off for the moment :-)
>>
>> Best wishes,
>>
>> Alan.
>



More information about the Agda mailing list