Closed Thimoteus closed 9 years ago
Did you see #283?
Changing the type signature to newWithConfig :: (Opts o, Requirable r) => o -> Ptr r -> Fay SnoocoreWithOpts
gives the same runtime error. Also I was also already wrapping the second argument in parentheses, which is a workaround for #283.
For now I'm just passing the config object and instantiating all at once.
I'll try to take a look later today, I'm guessing some type conversion/thunk is getting in the way. I have considered changing the FFI so Ptr/Automatic isn't needed but I'm not sure if it would cause problems elsewhere.
Sorry for the delay with this, I forgot about it!
The issue is that there's a polymorphic r
that is a function in this case, fay sees that and converts it back and forth to a fay-callable function, snoocore seems to expect it to stay intact and if they didn't do that check it's possible it would just work.
I found two ways to fix it, by using explicit types in ffi calls, or by adding Ptr
, both tell the fay runtime to not try to convert the result.
{-# LANGUAGE EmptyDataDecls #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE RebindableSyntax #-}
module Test where
import Data.Text (Text, fromString)
import FFI
import Prelude
import qualified Data.Text as T
class Requirable a
class Opts a
data Snoocore
data SnoocoreOpts
data SnoocoreWithOpts
instance Requirable Snoocore
instance Opts SnoocoreOpts
require' :: Requirable r => Text -> Fay (Ptr r)
require' = ffi "require(%1)"
newWithConfig :: (Requirable r, Opts o) => o -> Ptr r -> Fay SnoocoreWithOpts
newWithConfig = ffi "new (%2)(%1)"
snoocore :: Fay (Ptr Snoocore)
snoocore = require' "snoocore"
makeOpts :: Text -> Int -> Text -> Text -> Text -> Text -> Text -> [Text] -> SnoocoreOpts
makeOpts = ffi "{'userAgent': %1, 'throttle': %2, 'oauth': { 'type': %3, 'key': %4, 'secret': %5, 'username': %6, 'password': %7, 'scope': %8 }}"
main = do
let opts = makeOpts "/u/username myApp@3.0.0" 300 "script" "abcdefg" "1234567" "redditusername" "redditpassword" ["identity", "read", "vote"]
reddit <- newWithConfig opts =<< snoocore
print reddit
{-# LANGUAGE EmptyDataDecls #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE RebindableSyntax #-}
module Test where
import Data.Text (Text, fromString)
import FFI
import Prelude
import qualified Data.Text as T
class Requirable a
class Opts a
data Snoocore
data SnoocoreOpts
data SnoocoreWithOpts
instance Requirable Snoocore
instance Opts SnoocoreOpts
require' :: Text -> Fay Snoocore
require' = ffi "require(%1)"
newWithConfig :: Opts o => o -> Snoocore -> Fay SnoocoreWithOpts
newWithConfig = ffi "new (%2)(%1)"
snoocore :: Fay Snoocore
snoocore = require' "snoocore"
makeOpts :: Text -> Int -> Text -> Text -> Text -> Text -> Text -> [Text] -> SnoocoreOpts
makeOpts = ffi "{'userAgent': %1, 'throttle': %2, 'oauth': { 'type': %3, 'key': %4, 'secret': %5, 'username': %6, 'password': %7, 'scope': %8 }}"
main = do
let opts = makeOpts "/u/username myApp@3.0.0" 300 "script" "abcdefg" "1234567" "redditusername" "redditpassword" ["identity", "read", "vote"]
reddit <- newWithConfig opts =<< snoocore
print reddit
Hope this helps, feel free to ask more questions, I'll close this.
To preface, I'm not sure if this is my own fault, Fay's, node's babel's or the module I'm using.
The problem is I'm using a module that's usually used in two parts, something like
and when I try emulating that in Fay with
node throws an error when I run. On the other hand, if I do it all at once with something like
newAndRequire = ffi "new (require(%2))(%1)"
it works out fine.Here's the code I'm using:
This compiles and prints
[Function]
but if I comment out the "allAtOnce" line and uncomment the one above, I getTypeError: Cannot call a class as a function
, which apparently comes from babel.js, which the author of Snoocore used to write the module.I'm compiling with
fay --package fay-text Test.hs
, myfay --version
is0.23.1.5
, andnode --version
isv0.10.36
.