Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Qualified types in FFI declarations do not resolve (was: Text and Automatic, don't understand how come I get undefined) #349

Open
emmanueltouzery opened this issue Oct 17, 2013 · 5 comments
Labels

Comments

@emmanueltouzery
Copy link

This may be my misunderstanding of the library, but I don't understand how come after "test2" i get "undefined" as the value.
Maybe it's not supported to decode to Text and I should have the record type in "Type" to be String instead of Text?

Otherwise apologies for the contrived test code, this is extracted from my larger source.

{-# LANGUAGE NoImplicitPrelude, EmptyDataDecls, OverloadedStrings, RebindableSyntax #-}

import Fay.Text (Text, fromString)
import qualified Fay.Text as T
import FFI
import Prelude

data JValue

data Type = Type
    {
        keyName :: T.Text
    }

key :: Automatic Type
key = ffi "{'keyName':'key'}"

hash :: JValue
hash = ffi "{'key':'value'}"

jvValue :: JValue -> T.Text -> JValue
jvValue v k = jvValue' v (T.unpack k)

jvValue' :: JValue -> String -> JValue
jvValue' = ffi "%1[%2]"

jvValue1 :: JValue -> T.Text -> JValue
jvValue1 = ffi "%1[%2]"

jvGetString :: JValue -> T.Text
jvGetString = ffi "%1 + ''"

main = do
    let typeV = key
    let keyV = keyName typeV
    print "test1"
    putStrLn $ T.unpack $ jvGetString $ jvValue hash keyV
    print "test2"
    putStrLn $ T.unpack $ jvGetString $ jvValue1 hash keyV

I compile this with: fay --package fay-text --html-wrapper FayTest2.hs.

(as an aside I had assumed so far that if I call "ffi" then the return type must be in the Fay monad, turns out that not necessarily... So I guess it's the common sense of the author to decide to put the result in the Fay monad or not... Like if it will touch anything besides the parameters (DOM and so on) then put Fay, if it only reads the parameters without side-effects then no Fay..?)

@bergmark
Copy link
Member

Text decoding is supported, the reason Text was added was that it is represented as JS strings so transcoding is the identity. I have an inkling that you may need an unqualified import here. I completely forgot about the FFI when adding qualified imports! So please try edit import Fay.Text (Text). I may have time to look into it more tomorrow if this doesn't solve it.

Yes, Fay is never needed, but should be used for anything that may include a side effect. ffi "%1 + %2" is obviously pure. console.log is not. I find it's easy to choose most of the time, but there are cases I haven't made up my mind about like getWindow = ffi "window". The window object is always the same, but its properties mutate. I stick with Fay when uncertain. I'll add this to the wiki.

@emmanueltouzery
Copy link
Author

I already have import Fay.Text (Text, fromString) in my code, but I made it even import the whole Fay.Text with import Fay.Text but even doing that I still get undefined.

Thanks for the answer about the Fay monad!

@bergmark
Copy link
Member

I went back and forth with this one, it is a bug with qualified imports after all, T.Text doesn't force the thunk.

jvValue1 :: JValue -> T.Text -> JValue
jvValue1 = ffi "%1[%2]"

jvValue1' :: JValue -> Text -> JValue
jvValue1' = ffi "%1[%2]"

jvValue1'' :: JValue -> T.Text -> JValue
jvValue1'' = ffi "%1[Fay$$_(%2)]"
    print "test2"
    putStrLn $ T.unpack $ jvGetString $ jvValue1 hash keyV
    print "test3"
    putStrLn $ T.unpack $ jvGetString $ jvValue1' hash keyV
    print "test4"
    putStrLn $ T.unpack $ jvGetString $ jvValue1'' hash keyV
test2
undefined
test3
value
test4
value

And yes, I meant Fay.Text of course :) I'll update the comment in case someone else reads this ticket after having the problem.

@emmanueltouzery
Copy link
Author

ah yes sorry when I said it didn't help, i changed the import but did not remove the "T." in the definition... It simply didn't come to my mind that this could have any influence :-/

@bergmark
Copy link
Member

By the way key :: Automatic Type is equivalent to key :: Type. Automatic is only needed when it's placed on a type variable.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants