Skip to content

JSObject Wrapper Types

jbracker edited this page Mar 12, 2013 · 14 revisions

It is sometimes useful to introduce wrapper types (e.g. JSDate, JSCanvas) around JSObject to gain a bit more type safty. When implementing these don't forget to provide the following instances:

  • Sunroof - All these wrapper types should be sunroof values (otherwise they are useless).
  • BooleanOf - Without this binding using the type inside if-then-else is impossible.
  • IfB - Without ifB will not be available for the wrapper.
  • EqB - This should be implemented with reference equality to be consistent with Javascript. This also means it is always possible to implement this class.
  • SunroofValue - To ensure that combinators like array that provide a interface for Haskell and Sunroof values at the same time will work with your new type. You should at least give the identity instance.

Example

Here an example implemention for the not existing type JSWrapper. It is advised to provide the comment for EqB in the example to ensure that readers of the documentation know what is going on. The Show instance given is convenient for debugging but not necessary.

newtype JSWrapper = JSWrapper JSObject

instance Show JSWrapper where
  show (JSWrapper o) = show o

instance Sunroof JSWrapper where
  box = JSWrapper . box
  unbox (JSWrapper o) = unbox o

instance SunroofValue JSWrapper where
  type ValueOf JSWrapper = JSWrapper
  js = id

type instance BooleanOf JSWrapper = JSBool

instance IfB JSWrapper where
  ifB = jsIfB

-- | Reference equality, not value equality.
instance EqB JSWrapper where
  (JSWrapper a) ==* (JSWrapper b) = a ==* b

This requires the following imports and language extensions:

{-# LANGUAGE TypeFamilies #-}

import Data.Boolean ( BooleanOf, IfB(..), EqB(..) )
import Language.Sunroof.Classes ( Sunroof(..) )
import Language.Sunroof.JS.Bool ( JSBool, jsIfB )
import Language.Sunroof.JS.Object ( JSObject )
Clone this wiki locally