Closed crocket closed 7 years ago
Haste supports passing callbacks through the Haste.Foreign
FFI:
{-# LANGUAGE OverloadedStrings #-}
import Haste.Foreign
withPrompt :: (String -> IO ()) -> IO ()
withPrompt = ffi "(function(f){f(prompt('Name, please!'));})"
main = withPrompt $ \name -> putStrLn ("Hello, " ++ name)
While it doesn't support functions which are actually variadic (i.e. may be called with a different number of arguments each time), you can easily fake it using Maybe
arguments (currently only in 0.6 dev branch; 0.5.x doesn't consider undefined
to be Nothing
for marshalling purposes):
{-# LANGUAGE OverloadedStrings #-}
import Haste.Foreign
withPrompt :: (Maybe String -> IO ()) -> IO ()
withPrompt = ffi "(function(f){f();})"
main = withPrompt $ \mname -> do
case mname of
Just name -> putStrLn ("Hello, " ++ name)
_ -> putStrLn "No name. :("
This paper describes the FFI in detail. There isn't a lot of user-oriented documentation for the FFI in particular, but this example shows the basics through a very minimal jQuery example.
It seems Haste FFI overlaps to some degree with GHCJS FFI and ghcjs-base.
I mixed arguments
object with a variadic function to create variadic callback generators. They do not create variadic callbacks, but they can create any kind of callback. The variadic function merely maps haskell arguments to arguments
object.
If it was possible to convert a haskell function to a javascript function, the same trick as I used in ghcjs-base could be used. Can a haskell function be converted to a javascript function in Haste with ease? In other words, is there a clean way to turn a haskell function into JSAny
?
With Haste any Haskell function can be used as a callback, without having to call an explicit generator for it. If you want to do that anyway for some reason, you can just use the ToAny
instance for marshallable functions: some_callback = toAny $ \x y z -> putStrLn (concat [x, y, z])
.
As far as I understand, your variadic generator essentially allows the same thing but for the JSFFI, which is more restrictive about what values can be marshalled? If I'm mistaken here, could you give an example of a Haste program that would benefit from having this construction, to help me understand the idea a bit better?
Apologies for the late reply; things have been a bit hectic of late.
If any haskell function can be used as a callback in haste, then haste doesn't need my callback generator. GHCJS FFI is not very good.
A while ago, to ghcjs-base project, I submitted a pull request that adds variadic callback generators. You can read the details on https://github.com/crocket/ghcjs-base#callbacks-with-arbitrary-numbers-of-arguments.
Haste seems similar to GHCJS, and I wonder whether I can do the same with Haste.