maple calls to just a line or two of Haskell
code.
I don't know on Marshalling/UnMarshalling...
Marshaling/unmarshalling is converting the argument list from Haskell (or, for
that matter C) representation into Maple representation. Half the code in
your example was doing this.
--
Alastair Reid
Paterson has a very nice scheme
for doing this - but I can't find it in the mail archives at the moment.)
--
Alastair Reid
___
FFI mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/ffi
but gives an unexpected answer, say what
answer you get and what you expect. What compiler and version are you using?
Providing a _complete_ example we can try ourselves would be another thing to
try.
--
Alastair Reid
___
FFI mailing list
[EMAIL
to do something different to cause the DLL to be loaded or do you
have to invoke the function using a different calling convention or both?
--
Alastair Reid
___
FFI mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/ffi
And Hugs too. The issue isn't extending the FFI but implementing it
more accurately and consistently. As you point out, systems compiling
via C have been extending the FFI to a function+macro interface, which is
incompatible with systems compiling to native code. Having been bitten by
the
the result in a header file like this:
curses_wrapper.h:
#include curses.h
#ifdef __GHC__
#undef macro1
...
#undef macro117
#endif
and use curses_wrapper.h instead of curses.h in the Haskell code.
--
Alastair Reid
___
FFI
I think adding new (hierarchical) modules is the way to go for now.
1) Hierarchical because it lets us use some nice clear
module naming style like:
Foreign.NonStd.*
or
Foreign.Extension.*
[I favour the former since the status of the lib is clearer.]
I'm a bit uncertain
I can't see a simple solution. Perhaps we just declare that when a
newtype is exported abstractly, it's suitability as a foreign argument
type is still visible.
This feels a little like the global visibility of class instances.
If I export a type T abstractly, all its instances are exported
the trick.
%fun doStuff :: Int - Int - IO (Int,Int)
%code doStuff(arg1,arg2)
%return ({*arg1},{*arg2})
--
Alastair Reid
___
FFI mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/ffi
(1994), the names of the operations and their
types has changed quite a bit. See the current specification for details:
http://www.cse.unsw.edu.au/~chak/haskell/ffi/
--
Alastair Reidwww.haskell-consulting.com
___
FFI mailing list
[EMAIL PROTECTED
think about implementing peekByteOff like this:
peekByteOff p o = peek (plusPtr p o)
And, since peekByteOff is primarily for use when peekElemOff doesn't work
(i.e., for structs), it makes sense to change the type.
--
Alastair Reid
___
FFI mailing list
environment object for a set
of objects (e.g., for all objects of the same 'type'), the finalizer might
decrement a reference count on the environment object.
Have I missed some subtlety?
--
Alastair Reid
Regarding
type FinalizerEnvPtr env a = FunPtr (Ptr env - Ptr a - IO
.
To be honest, I can't think of many cases where I would want the
types you propose. peekElemOff is basically for arrays where all elements
have the same type - why would you want to treat them as having different
types?
--
Alastair Reid
Never say never... The signatures for peekElemOff
values -just load
up multiple registers or put multiple values on the stack- but in C, there is
no good way to return multiple values.
--
Alastair Reid
___
FFI mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/ffi
On Tuesday 22 July 2003 3:20 pm, Ross Paterson wrote:
OK, so the thing I want shouldn't be called stdcall, but it would be useful
(and is already being used).
Yes to both.
Especially so if any other platform has two commonly used calling convention.
--
Alastair
On Saturday 19 July 2003 12:51 am, Ross Paterson wrote:
Could the meaning of stdcall be broadened to the standard calling
convention for libraries on the native system, i.e. pascal on Win32
(as now) and ccall on Unix? It would save a lot of fuss for interfaces
to portable libraries.
If I
).
These issues were considered important because one goal of the ffi spec was to
improve portability between implementations and also because we explicitly
decided not to do anything that requires concurrency or other H98 extensions.
--
Alastair Reid
The need for nullForeignPtr arises when a function expects
a pointer to some data structure or a null pointer. In this case I cannot
make the foreign import have the type (Maybe (ForeignPtr ()) since it's not
accepted by the FFI.
I guess I've mostly used this trick with GreenCard whcih
the discussion on ForeignPtrs without finalizers didn't come to a
conclusion. I specifically need the nullForeignPtr which was easy enough
with the FFI of GHC 5.04:
[...]
do I have to create a dummy C function?
Yes, create a dummy C function.
(Actually, you could use 'free' since it does
this though since I believe they would always be
used with singleton or empty arguments and because the list-based versions
can be trivially added with a foldM if they prove useful.
--
Alastair Reid
___
FFI mailing list
[EMAIL PROTECTED]
http://www.haskell.org
Actually, I think I prefer Ashley's idea of separating the creation of a
ForeignPtr from the addition of a FinalizerPtr. So how about:
newForeignPtr :: Ptr a - IO (ForeignPtr a)
addForeignPtrFinalizer :: FinalizerPtr a - ForeignPtr a - IO ()
You're proposing a different
you explain what you're trying to do and whether you think we
shoud provide direct support for newSimpleForeignPtr (which I'd be tempted to
call newForeignPtr_).
--
Alastair Reid
___
FFI mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman
Ashley:
How do I create a new ForeignPtr that doesn't have any finalizers?
Malcolm:
Why would you want to?
addForeignPtrFinalizer lets you add them later.
I'm guessing that Ashley is making heavy use of this ability.
[What we have at the moment is the ability to attach a non-empty list of
).
I agree with adding newForeignPtr_. (Presumably the report would define
newForeignPtr in terms of newForeignPtr_ and addForeignPtrFinalizer.)
I'd prefer to avoid swapping the argument order because of code breakage.
--
Alastair Reid
___
FFI mailing
You want to use a tool to make all this easier. There are various tools
available: green-card, c2hs, and hsc2hs are the most commonly-used ones
these days.
Alastair Reid wrote a good comparison of the various tools
(can't remember the link off hand though).
It is in:
http://www.reid
ok, I'm convinced. The semantics of empty datatypes can be a type inhabited
only by bottom.
Hugs implements exactly that.
[Except in the special case of a few magical names (Int, Float, etc) when they
occur in the Prelude (and only then). Since it is only usable in the
Prelude, they can be
should make sure the syntax and semantics are tolerably
clear and in agreement with each other.
--
Alastair Reid
___
FFI mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/ffi
think
data Int
with a builtin type is a different thing from what we're doing when we write:
data T
for some foreign type.
--
Alastair Reid
___
FFI mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/ffi
I'm not following this. what exactly is derefPtr? The only analogous
function I can think of is Foreign.peek:
Sorry, I meant peek.
but peek will unmarshal the value at the end of the Ptr into T, so T
cannot be abstract.
Sorry, I was just trying to show how to create a value of type
T
optimizations implemented by
different compilers.
--
Alastair Reid [EMAIL PROTECTED]
Reid Consulting (UK) Limited http://www.reid-consulting-uk.ltd.uk/alastair/
___
FFI mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman
requirements
are quite modest (so, hopefully, portable) so I think an
implementation is pretty likely to happen. Timescale will depend on
when people find time or money to do it.
--
Alastair Reid [EMAIL PROTECTED]
Reid Consulting (UK) Limited http://www.reid-consulting-uk.ltd.uk
work on an ffi tutorial. At the moment it concentrates on
how to use the various compilers, frontend tools to use with the ffi,
etc. but it has pointers to the documentation, mail on the ffi list
about how to use the ffi, etc.
--
Alastair Reid [EMAIL PROTECTED]
Reid Consulting
this guarantee.
--
Alastair Reid [EMAIL PROTECTED]
Reid Consulting (UK) Limited http://www.reid-consulting-uk.ltd.uk/alastair/
___
FFI mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/ffi
Was any decision reached about foreign dependencies?
--
Alastair
___
FFI mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/ffi
I think that should be the reverse order. For example, if you add a
finalizer to the result of mallocForeignPtr, you want it to run
before the thing is freed. (That's what Hugs does now.)
Sorry, yes, of course.
--
Alastair
___
FFI mailing list
Sorry to ask this again, but I didn't understand the answer last
time, and the need to explicitly free StablePtr's, Haskell FunPtr's
and close foreign handles, etc, is surely a serious wart in the FFI
spec.
I don't understand part of this. StablePtrs exist so that you can
hand them to C.
On first glance, this looks cool. What instances do you envision
(assuming I persuaded you that StablePtr and FunPtr should not be)?
How about Int (for file descriptors, etc)?
Ah, got you.
How about making ForeignPtr slightly more polymorphic so that instead of
working only on 'Ptr a' it
obviously, we'd want to remove the word 'Ptr' from the name of the
type. Candidates:
ForeignProxy, ForeignObj, Foreign
I think 'Foreign' is an essential part (at least, given the
restriction to C finalizers) and I favour the first two over the
last which seems too general.
Maybe
perhaps ForeignPtr should not be an instance of Eq so people can
provide their own?
Note that if we did this, we'd want to consider adding an operation
eqForeignPtr :: FP a - FP a - Bool
FP b-- possible variant but not very useful
which lets people test
the story is that multiple spaces are
allowed, tabs are allowed and any two tokens may be separated by
spaces. If you catch Hugs behaving otherwise, I'll fix it.
--
Alastair Reid [EMAIL PROTECTED]
Reid Consulting (UK) Limited http://www.reid-consulting-uk.ltd.uk/alastair
token - special | | fname | cid | whitespace
special - static | dynamic | wrapper
fname - ... .h (... as I don't have [3] handy)
cid - ... excluding special (... as I don't have [3] handy)
whitespace - { ' ' | '\t' }
For what it's worth, Hugs uses 'any non-empty sequence of
code:
Foo.so: Foo.hs foo.c bar.o
ffihugs +G Foo.hs -Lfoo.c -Lbar.o -L-lm
You'll also find the file in ${installdir}/lib/hugs/include/HsFFI.h
--
Alastair Reid [EMAIL PROTECTED]
Reid Consulting (UK) Limited http://www.reid-consulting-uk.ltd.uk/alastair
[EMAIL PROTECTED] pisze:
keepAlive x y ensures that the finalizer for y is not run
until after the finalizer for x has run to completion.
Marcin:
What if I do keepAlive p1 p2 keepAlive p2 p1? They will never be
collected?
Correct.
I'm a bit vague about what liveness dependencies are
John Meacham [EMAIL PROTECTED] writes:
here are my canidate suggestions:
* add a subset of Weak pointers
Can you spell this out in detail. What are the functions? What are
their semantics?
- or -
* add addForeignDependency :: ForeignPtr a - ForeignPtr b - IO ()
Again, could you spell
Just before this gets out of the door... any chance of calling it
modifyIORef
and documenting that it's atomic? Sometimes names can get too long!
There's two reasons you might use the function: convenience and atomicity.
I can easily imagine someone modifying a program, thinking
[snip] How sad. It's an unfortunate hole in the specification and I
hope someone will come up with a way of fixing it someday.
I don't think it'll happen until preemptive concurrency is more widely
implemented.
In the meantime, I'm glad we have got a new function
atomicModifyIORef which I
The problem is that the G-machine optimizes away some of the
updates which make sure that the heap is always in a consistent
state in a pure graph-reduction system.
A pure G-machine updates all redexes, but the STG-machine only
updates /shared/ redexes, yes?
It's a while since I looked at
SimonM:
My impression is that the problem is more fundamental: the thunk for
x is under evaluation when the finalizer begins to run,
Urgle.
probably we shouldn't get a crash, but a blackhole instead.
Even a blackhole is wrong. There's no cycle so it ought to evaluate
successfully.
Alastair:
On a system where finalizers behave like preemptive threads
[nonsense deleted]
My outline of consequences/ implementation for GHC-like systems was
completely wrong because I was still thinking about finalizers as
special cases.
What needs to happen on GHC-like systems is that
Alastair:
So, is this a design that we could agree on?
SimonM:
I like it. I'd vote for 'atomicModifyIORef' rather than a new PVar
type, though.
Ok, onto the second question:
Can we use atomicModifyIORef to make our code finalizer-safe?
I see potential problems wherever two IORefs need
Alastair:
I don't know how to achieve the same goal with atomicModifyIORef.
George:
I do. To modify ioRef1 and ioRef2 simultaneously, write
atomicModifyIORef ioRef1 (\ contents1 -
unsafePerformIO ioRef2 (\ contents2 -
blah blah))
The actual modification will take
Ross Paterson [EMAIL PROTECTED] writes:
there's an unsafe use in evalName(),
I think this is easily fixed by using malloc to allocate the buffer
and then tracking down all uses and calling free.
and I don't understand the mutual recursion between eval() and run().
Not sure what you don't
However we don't really need to discuss this anyway, since I don't
think either runAtomically or atomicallyModifyIORef need to be in
the FFI standard. I'm quite happy to leave this open.
As usual, I disagree. I think the FFI spec would be incomplete if it
provided Haskell finalizers but no
I don't like runAtomically either, because once again it assumes a
global lock.
It has to be a global lock if we are to implement it on NHC and Hugs.
Since we can't block finalizers once they start running, the only way
to get atomicity is to stop them running. This requires use of a
global
Alastair:
Since 90% of uses of runAtomically will be with modifyIORef, we
can avoid this overhead by providing atomicModifyIORef in the IORef
library as well. Multiprocessor GHC is free to implement it more
efficiently if necessary/ convenient.
[snip] I'm not convinced the overhead is
Since we've talked about mutable state quite a lot, my suggestion
would be that we write, in addition to the FFI specification, a
Mutable State specification which documented newIORef, readIORef,
writeIORef, atomicModifyIORef (and possibly, for reasons of
efficiency, atomicModifyIORef_). I
However in general I think we can hide some of the horribleness from
the user:
modify2IORefs :: IORef a - IORef b - (a - b - (a,b,c)) - IO c
[horrible code deleted]
And if they need to update 3 IORefs or a list of IORefs?
Writing code like that yourself and getting it right and portable
Could we not at least replace the global lock by a local one?
I refer the honourable gentleman to my previous answer.
--
Alastair
___
FFI mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/ffi
Worse though, I don't even know what semantic framework to use to
reason about it if we want to be sure the code will work in the
presence of strictness analyzers, eager evaluation, parallel
evaluation, fully-lazy evaluation, etc. Operational reasoning and
reasoning by example struggle with
George writes:
If you have Haskell talking to some
other language with a garbage collector, be it Java or SML, then at
a given point of the program you can in general expect to have
Haskell holding stable pointers to objects referenced from their
world by the other language, and vice-versa.
(2) blockFinalizers looks fine for Hugs and NHC which only have a
single-thread model, but it looks tricky in general where [...]
Ah, I see what you mean.
I'd kinda hardwired into the definition the assumption that finalizers
run at higher priority than other threads and that there's a
So what you want is for the Java GC to call hs_freeStablePtr on all
the Haskell objects that just died?
No, that's only a partial (and indeed very incomplete) solution. It
relies on the Java GC knowing that that particular reference to the
Haskell StablePtr is the only one that matters,
So, are we now claiming that my patch *is* safe? (Never mind about
IORefs, I'm talking about the implementation itself).
No.
And my recent focus on IORefs has simply been because they seemed the
strongest argument.
A
___
FFI mailing list
[EMAIL
(It would be nice to have some concurrency in nhc98, of course, but
I don't foresee that happening soon.)
I remember implementing cooperative concurrency in Hugs as being
rather easy. Of course, that was building on a base which already used
a continuation passing IO monad...
If you want to
However even if Haskell finalizers + MVars are impossible in NHC, I
don't think Haskell finalizers + mutable state have to be. For
example another mutable variable we could have would be a PVar which
is always full and has functions [snip]
updatePVar (PVar ioRef) updateFn =
do
[snip] I don't see that it's necessary for us to come to a decision
right now about PVars unless we want to put them in the FFI
standard.
But what if we can't agree on something like PVars or we decide that
Haskell finalizers plus yet another synchronization mechanism is worse
than C
For the record, I am strongly in favor of Haskell finalizers, if a
Mutable State extension were to be written, then it will have to
address the issue with one of the solutions mentioned in this
thread,
We already have a perfectly good Mutable State extension. We know
exactly what it looks
| To get any benefit from writing finalizers in Haskell, I have to have
| MVars which protect against finalizers.
Nearly right, but not quite. You might write a Haskell finalizer
that did lots of useful things (e.g. consulted a large pure data
structure) before doing its state-mutation by
I don't think = is frequent enough. Pure code that manipulates
big C objects (remember that image processing example of mine?) can
generate a lot of garbage C objects without once going into the IO
monad.
Also, thanks to unsafePerformIO, = can be invoked during execution
of a primitive
Yes, that's right. It is often the case that there *is* no shared
state so a Haskell finalizer is fine. But if there is, then there
has to be some mechanism for atomic operations. C is one such
mechanism.
I claim that the major thing that finalizers do is manipulate shared
state. Their
depend on a
concurrency standard. I think there was a strong sentiment that we
should avoid this. I agree though that it is necessary if we allow
Haskell finalizers.
--
Alastair Reid [EMAIL PROTECTED]
Reid Consulting (UK) Limited http://www.reid-consulting-uk.ltd.uk/alastair
What hasn't been required is for the various data structures to be
in a consistent state at that point, and Haskell finalizers might
trip over those if run after GC. SimonM's patch ran them at a
different point, though.
It calls them in eval doesn't it?
eval is called by nearly every
will not
actually fix the problem, it will just change the allocation/GC
pattern so that the problem doesn't show up in the test.
--
Alastair Reid [EMAIL PROTECTED]
Reid Consulting (UK) Limited http://www.reid-consulting-uk.ltd.uk/alastair
.)
AFAIK, NHC does not implement any concurrency primitives so NHC would
have to add them before it can provide any useful form of Haskell
finalizers.
--
Alastair Reid [EMAIL PROTECTED]
Reid Consulting (UK) Limited http://www.reid-consulting-uk.ltd.uk/alastair
or performGC we check whether the bit is set. Making this
work in a multithreaded setting like GHC would be more painful and
more expensive but probably feasible.
--
Alastair Reid [EMAIL PROTECTED]
Reid Consulting (UK) Limited http://www.reid-consulting-uk.ltd.uk/alastair
changes and
doesn't seem like evidence of awkwardness to me.
--
Alastair Reid [EMAIL PROTECTED]
Reid Consulting (UK) Limited http://www.reid-consulting-uk.ltd.uk/alastair/
___
FFI mailing list
[EMAIL PROTECTED]
http://www.haskell.org
Then I'll reformulate my question as a patch. [...]
Is there anything fundamentally wrong with this approach?
I still maintain that getting this to work, testing it and,
especially, maintaining it is a lot of work. [For example, you
mention that finalizers that point to the object they
Still hoping ;-) The discussion seemed to stop without reaching a
conclusion last time.
I thought it was concluded and the report changed such that all three
compilers which implement the ffi spec can implement it without
receiving a heart, lung and liver transplant.
At least, I still don't
Alastair wrote:
I seem to remember that Sigbjorn and Erik dealt with this problem by
arranging some kind of GC-visible link between the objects so that
until the second finalizer has run, the object will not be
considered garbage.
Sorry, this was nonsense - I hadn't noticed that is was a
over.
--
Alastair Reid [EMAIL PROTECTED]
Reid Consulting (UK) Limited http://www.reid-consulting-uk.ltd.uk/alastair/
___
FFI mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/ffi
... maybe I'm being stupid, but I don't see what the problem is.
Why can't mallocForeignPtr be implemented as:
mallocForeignPtrBytes size = do
r - c_malloc (fromIntegral size)
newForeignPtr r ptr_c_free
foreign import ccall unsafe malloc
c_malloc :: CInt - Ptr a
Alastair:
(In the image processing example, images were megabytes and an
expression like (x + (y * mask)) would generate 2 intermediate
images (several megabytes) while doing just 2 reductions in
Haskell.)
Marcin:
OCaml allows the programmer to specify an approximate amount of
foreign
wonder
if it would be any easier to implement? The communication would be
much the same ('I'm starting', 'I can reach X' and 'I'm done') but
there'd be no need to synchronize the GCs.
--
Alastair Reid [EMAIL PROTECTED]
Reid Consulting (UK) Limited http://www.reid-consulting
(i.e., implementation dependent)
way. We could insert the word 'full' and leave it to people's
imaginations?
--
Alastair Reid [EMAIL PROTECTED]
Reid Consulting (UK) Limited http://www.reid-consulting-uk.ltd.uk/alastair/
___
FFI
.
--
Alastair Reid [EMAIL PROTECTED]
Reid Consulting (UK) Limited http://www.reid-consulting-uk.ltd.uk/alastair/
___
FFI mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/ffi
I think the thing to do is add the existing performGC to the standard
(perhaps giving it an hs_ prefix in the process) and leave development
of an extended version of the function for when the GHC folk (or
anyone else with a generational collector) decide they want a
forcefulness argument. Come
Errm, but in C there is no unified shift operator. You have for
left shift and and for right shift, and a negative shift is
undefined.
[blush]
This makes the specification come out nice and clean - you're
multiplying the number by 2^n instead of 2^{-n}.
Errm, but then right shift
can attach a
reference counter, you somehow always find yourself faced with the
problem that a C library hands you a pointer to an unwrapped object
and you have to try to track down the reference counter for it.
Any ideas welcome.
--
Alastair Reid [EMAIL PROTECTED]
Reid Consulting
circumstances, rather than to the GHC documentation to say that
actually they do.
It's a matter of taste how you do these things.
--
Alastair Reid [EMAIL PROTECTED]
Reid Consulting (UK) Limited http://www.reid-consulting-uk.ltd.uk/alastair
Nevertheless, I think even without the tricks I'm using in GHC, the
case where a ForeignPtr is used in conjunction with malloc()/free()
is one which is likely to be optimisable in any system with its own
memory management.
I wasn't meaning so much that only GHC could take advantage of it
go ahead and list them as non-standard extensions]
There's a minor issue about whether the old function names should be
reused (leaving GHC to come up with its own names) or not. I have
ceased to care either way.
--
Alastair Reid [EMAIL PROTECTED]
Reid Consulting (UK
Can you achieve the same performance gain by adding some rewrite rules?
--
Alastair
___
FFI mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/ffi
At the moment, there are two kinds of initialisation done for each
module:
Both ELF and DLLs on Windows provide a way of specifying initializers.
Or, easier yet, since the user is already using the hs_init function,
you could use that. The way you'd do that in ELF is to define a
special
Under .NET each DLL has its own namespace, so the [lib] spec is
needed to disambiguate. Since it's a namespace issue, I'd feel
better if on .NET the name of the C function took a different form
(perhaps lib.function) and [lib] is removed from the spec.
Isn't that just a different syntax
at the moment so I can't
say for sure. I think it can be done as a thin layer on top of the
the existing spec though so I don't think it's that hard.
--
Alastair Reid [EMAIL PROTECTED]
Reid Consulting (UK) Limited http://www.reid-consulting-uk.ltd.uk/alastair
actually *very* reluctant to introduce new names. On the other
hand, reusing the old names will lead to a couple of unhappy emails
from people using the old interface again.
But only a couple I conjecture.
--
Alastair Reid [EMAIL PROTECTED]
Reid Consulting (UK) Limited http
--
Alastair Reid [EMAIL PROTECTED]
Reid Consulting (UK) Limited http://www.reid-consulting-uk.ltd.uk/alastair/
___
FFI mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/ffi
free
...
All the rest of your code to manipulate ForeignPtrs remains the same.
(Well, there's a corresponding change in addForeignFinalizer if you
happen to use that.)
--
Alastair Reid [EMAIL PROTECTED]
Reid Consulting (UK) Limited http://www.reid-consulting-uk.ltd.uk
if the ffi is not portable but only n
combinations to worry about if the ffi is portable between
compilers.
--
Alastair Reid[EMAIL PROTECTED]http://www.cs.utah.edu/~reid/
___
FFI mailing list
[EMAIL PROTECTED]
http://www.haskell.org
Errm, shouldn't that be: [...]
Or is there some other trick involved here?
Sorry, yes it should - just me getting confused in translating between
Haskell's
f :: A - B
and C's
B f(A);
A
___
FFI mailing list
[EMAIL PROTECTED]
1 - 100 of 120 matches
Mail list logo