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 86 forks source link

Equality instances in Fay #455

Closed schnecki closed 5 years ago

schnecki commented 6 years ago

Hi,

first of all I'd like to say thank you for providing Fay. I've been working with it the last couple days and it makes my life much easier by using Haskell on the server and client. Thanks.

I'm currently working on a DOM package that copies document nodes [1], ranges, selection, etc. into Fay for processing. There I have following (simplified) data structure:

data Child 
  = ChildLink Element
  | ChildNode Node

instance Eq Child where
  x == y = fromChild x == fromChild y

fromChild :: Child -> Node
fromChild (ChildLink e) = unsafePerformFay $ toNode e
fromChild (ChildNode n)   = n

The idea is to use links to Elements (from fay-dom) whenever possible for performance and once the data of a ChildLink is needed, it is loaded from the HTML document. In case of (==) I use unsafePerformIO to do this. However, I feel like (==) is never executed, but equality is checked directly in JavaScript on the provided data. Clearly does not work when checking equality for ChildNodes and ChildLinks as they will never be loaded. Is this true?

If I preprocess the data structures by converting all ChildLinks to ChildNodes it does work at least.

Best wishes Manuel

[1] https://developer.mozilla.org/en-US/docs/Web/API/Node/nodeType

bergmark commented 5 years ago

Sorry for the late reply. fay doesn't have full type class support and in this case it ignores the implementation. It's unintuitive but part of the reason is so you can re-use the type definitions when compiling with GHC and still get instance deriving without orphan instances. You can define and use a custom equality function instead.

schnecki commented 5 years ago

Ah ok, I see. Yeah that makes sense. Thanks.