faylang / fay

A proper subset of Haskell that compiles to JavaScript
https://github.com/faylang/fay/wiki
BSD 3-Clause "New" or "Revised" License
1.29k stars 89 forks source link

Type aliases are not resolved in FFI conversions #185

Open bergmark opened 11 years ago

bergmark commented 11 years ago

Reported by cmccann and lucca on irc, I reproduced it like this:

import Language.Fay.FFI
import Language.Fay.Prelude

type S = String

data R = R S
instance Foreign R

data Q = Q String
instance Foreign Q

main :: Fay ()
main = do
  putStrLn ("hej" :: S)
  putStrLn ("hej" :: String)
  print $ R "hej"
  print $ Q "hej"

=>

hej
hej
{ instance: 'R',
  slot1: { car: 'h', cdr: { car: 'e', cdr: [Object] } } }
{ instance: 'Q', slot1: 'hej' }

So if the ffi signature is concrete as in putStrLn the encoding works, but not for the generic print.

bergmark commented 11 years ago

And fayToJs and jsToFay looks like this:

  if (_obj instanceof $_Main$R) {
    var obj_ = {"instance": "R"};
    var obj_slot1 = Fay$$fayToJs(["user","S",[]],_(_obj.slot1));
    if (undefined !== obj_slot1) {
      obj_['slot1'] = obj_slot1;
    }
    return obj_;
  }

  if (obj["instance"] === "Q") {
    return new $_Main$Q(Fay$$jsToFay(["string"],obj["slot1"]));
  }
  if (obj["instance"] === "R") {
    return new $_Main$R(Fay$$jsToFay(["user","S",[]],obj["slot1"]));
  }

Can we fix this with a Map Name Name for type aliases?

chrisdone commented 11 years ago

Yeah, I guess we can do that. There'll need to be a little bit of Type -> Type resolving, too (e.g. type Foo a = String and then Foo IntString). I mentioned this on IRC months ago but forgot to make a ticket.

bergmark commented 11 years ago

Does Automatic solve this (temporarily)? It might be a good idea to give a warning until this is implemented properly.

jameshfisher commented 11 years ago

I just hit this; I don't think Automatic does solve it, if I'm using it correctly:

module Aliases where

import Prelude
import FFI

type Name = String

alert :: Automatic Name -> Fay ()
alert = ffi "window['alert'](%1)"

main :: Fay ()
main = alert "James"

alerts "[Object object]". Same for without Automatic.

jazmit commented 11 years ago

:+1: encountered this issue.. also tried using Automatic without success. Stripping type aliases out of my code has solved this temporarily, but it's not a nice solution.