jsaddle-0.9.9.0: src/Language/Javascript/JSaddle/Value.hs
{-# LANGUAGE CPP #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE TypeSynonymInstances #-}
{-# LANGUAGE LambdaCase #-}
#ifdef ghcjs_HOST_OS
{-# LANGUAGE ForeignFunctionInterface, JavaScriptFFI #-}
{-# OPTIONS_GHC -Wno-dodgy-exports -Wno-dodgy-imports #-}
#endif
{-# OPTIONS_GHC -fno-warn-orphans #-}
-----------------------------------------------------------------------------
--
-- Module : Language.Javascript.JSaddle.Value
-- Copyright : (c) Hamish Mackenzie
-- License : MIT
--
-- Maintainer : Hamish Mackenzie <Hamish.K.Mackenzie@googlemail.com>
--
-- | Deals with JavaScript values. These can be
--
-- * null
--
-- * undefined
--
-- * true | false
--
-- * a double precision floating point number
--
-- * a string
--
-- * an object
--
-----------------------------------------------------------------------------
module Language.Javascript.JSaddle.Value (
-- * JavaScript value references
JSVal
, ToJSVal(..)
-- * Haskell types for JavaScript values
, JSNull(..)
, JSUndefined
, JSString
, JSValue(..)
, showJSValue
-- * Converting JavaScript values
, isTruthy
, valToBool
, valToNumber
, valToStr
, valToObject
, valToText
, valToJSON
-- * Make JavaScript values from Haskell ones
, val
, jsNull
, valNull
, isNull
, valIsNull
, jsUndefined
, valUndefined
, isUndefined
, valIsUndefined
, maybeNullOrUndefined
, maybeNullOrUndefined'
, toJSBool
, jsTrue
, jsFalse
, valBool
, valMakeNumber
, valMakeString
, valMakeText
, valMakeJSON
-- * Convert to and from JSValue
, deRefVal
, valMakeRef
, strictEqual
, instanceOf
) where
import Data.Text (Text)
import qualified Data.Text as T (pack, unpack)
import Data.Aeson (Value)
import Data.JSString.Text (textToJSString)
#ifdef ghcjs_HOST_OS
import Language.Javascript.JSaddle.Types
(Object(..), JSString(..), JSVal(..), ghcjsPure)
import GHCJS.Marshal (ToJSVal(..))
#else
import Data.Char (chr, ord)
import Data.Word (Word, Word8, Word16, Word32)
import Data.Int (Int8, Int16, Int32)
import GHCJS.Marshal.Internal (ToJSVal(..), FromJSVal(..))
import Language.Javascript.JSaddle.Types
(Object(..), JSString(..), JSVal(..), ghcjsPure)
import Language.Javascript.JSaddle.Native
(valueToNumber, valueToString, valueToJSON, numberToValue, stringToValue, jsonValueToValue)
import qualified Language.Javascript.JSaddle.Native as N
(deRefVal, strictEqual, instanceOf)
import Language.Javascript.JSaddle.Run (Result(..))
#endif
import Language.Javascript.JSaddle.Monad (JSM)
import Language.Javascript.JSaddle.Classes
(MakeObject(..), MakeArgs(..))
import Language.Javascript.JSaddle.Marshal.String (ToJSString(..), FromJSString(..))
import Language.Javascript.JSaddle.String (strToText, textToStr)
import GHCJS.Foreign.Internal (jsTrue, jsFalse, jsNull, toJSBool, jsUndefined, isTruthy, isNull, isUndefined)
-- $setup
-- >>> import Language.Javascript.JSaddle.Test (testJSaddle)
-- >>> import Language.Javascript.JSaddle.Monad (catch)
-- >>> import Language.Javascript.JSaddle.Exception (JSException(..))
-- >>> import Language.Javascript.JSaddle.Object (obj, jsg)
-- >>> import qualified Data.Text as T (pack)
data JSNull = JSNull -- ^ Type that represents a value that can only be null.
-- Haskell of course has no null so we are adding this type.
type JSUndefined = () -- ^ A type that can only be undefined in JavaScript. Using ()
-- because functions in JavaScript that have no return, impicitly
-- return undefined.
-- type JSBool = Bool -- ^ JavaScript boolean values map the 'Bool' haskell type.
-- type JSNumber = Double -- ^ A number in JavaScript maps nicely to 'Double'.
-- type JSString = Text -- ^ JavaScript strings can be represented with the Haskell 'Text' type.
-- | An algebraic data type that can represent a JavaScript value. Any JavaScriptCore
-- 'JSVal' can be converted into this type.
data JSValue = ValNull -- ^ null
| ValUndefined -- ^ undefined
| ValBool Bool -- ^ true or false
| ValNumber Double -- ^ a number
| ValString Text -- ^ a string
| ValObject Object -- ^ an object
-- | Show a JSValue but just say "object" if the value is a JavaScript object.
showJSValue :: JSValue -> String
showJSValue ValNull = "null"
showJSValue ValUndefined = "undefined"
showJSValue (ValBool True) = "true"
showJSValue (ValBool False) = "false"
showJSValue (ValNumber x) = show x
showJSValue (ValString s) = show s
showJSValue (ValObject _) = "object"
-- | Given a JavaScript value get its boolean value.
-- All values in JavaScript convert to bool.
--
-- >>> testJSaddle $ valToBool JSNull
-- false
-- >>> testJSaddle $ valToBool ()
-- false
-- >>> testJSaddle $ valToBool True
-- true
-- >>> testJSaddle $ valToBool False
-- false
-- >>> testJSaddle $ valToBool (1.0 :: Double)
-- true
-- >>> testJSaddle $ valToBool (0.0 :: Double)
-- false
-- >>> testJSaddle $ valToBool ""
-- false
-- >>> testJSaddle $ valToBool "1"
-- true
valToBool :: ToJSVal value => value -> JSM Bool
valToBool value = toJSVal value >>= ghcjsPure . isTruthy
-- | Given a JavaScript value get its numeric value.
-- May throw JSException.
--
-- >>> testJSaddle $ show <$> valToNumber JSNull
-- 0.0
-- >>> testJSaddle $ show <$> valToNumber ()
-- NaN
-- >>> testJSaddle $ show <$> valToNumber True
-- 1.0
-- >>> testJSaddle $ show <$> valToNumber False
-- 0.0
-- >>> testJSaddle $ show <$> valToNumber (1.0 :: Double)
-- 1.0
-- >>> testJSaddle $ show <$> valToNumber (0.0 :: Double)
-- 0.0
-- >>> testJSaddle $ show <$> valToNumber ""
-- 0.0
-- >>> testJSaddle $ show <$> valToNumber "1"
-- 1.0
valToNumber :: ToJSVal value => value -> JSM Double
#ifdef ghcjs_HOST_OS
valToNumber value = jsrefToNumber <$> toJSVal value
foreign import javascript unsafe
#if __GLASGOW_HASKELL__ >= 900
"(($1) => { return Number($1); })"
#else
"$r = Number($1);"
#endif
jsrefToNumber :: JSVal -> Double
#else
valToNumber value = toJSVal value >>= valueToNumber
#endif
-- | Given a JavaScript value get its string value (as a JavaScript string).
-- May throw JSException.
--
-- >>> testJSaddle $ strToText <$> valToStr JSNull
-- null
-- >>> testJSaddle $ strToText <$> valToStr ()
-- undefined
-- >>> testJSaddle $ strToText <$> valToStr True
-- true
-- >>> testJSaddle $ strToText <$> valToStr False
-- false
-- >>> testJSaddle $ strToText <$> valToStr (1.0 :: Double)
-- 1
-- >>> testJSaddle $ strToText <$> valToStr (0.0 :: Double)
-- 0
-- >>> testJSaddle $ strToText <$> valToStr ""
-- <BLANKLINE>
-- >>> testJSaddle $ strToText <$> valToStr "1"
-- 1
valToStr :: ToJSVal value => value -> JSM JSString
#ifdef ghcjs_HOST_OS
valToStr value = jsrefToString <$> toJSVal value
foreign import javascript unsafe
#if __GLASGOW_HASKELL__ >= 900
"(($1) => { return $1.toString(); })"
#else
"$r = $1.toString();"
#endif
jsrefToString :: JSVal -> JSString
#else
valToStr value = toJSVal value >>= valueToString
#endif
-- | Given a JavaScript value get its string value (as a Haskell 'Text').
-- May throw JSException.
--
-- >>> testJSaddle $ show <$> valToText JSNull
-- "null"
-- >>> testJSaddle $ show <$> valToText ()
-- "undefined"
-- >>> testJSaddle $ show <$> valToText True
-- "true"
-- >>> testJSaddle $ show <$> valToText False
-- "false"
-- >>> testJSaddle $ show <$> valToText (1.0 :: Double)
-- "1"
-- >>> testJSaddle $ show <$> valToText (0.0 :: Double)
-- "0"
-- >>> testJSaddle $ show <$> valToText ""
-- ""
-- >>> testJSaddle $ show <$> valToText "1"
-- "1"
valToText :: ToJSVal value => value -> JSM Text
valToText jsvar = strToText <$> valToStr jsvar
-- | Given a JavaScript value get a JSON string value.
-- May throw JSException.
--
-- >>> testJSaddle $ strToText <$> valToJSON JSNull
-- null
-- >>> testJSaddle $ strToText <$> valToJSON ()
-- <BLANKLINE>
-- >>> testJSaddle $ strToText <$> valToJSON True
-- true
-- >>> testJSaddle $ strToText <$> valToJSON False
-- false
-- >>> testJSaddle $ strToText <$> valToJSON (1.0 :: Double)
-- 1
-- >>> testJSaddle $ strToText <$> valToJSON (0.0 :: Double)
-- 0
-- >>> testJSaddle $ strToText <$> valToJSON ""
-- ""
-- >>> testJSaddle $ strToText <$> valToJSON "1"
-- "1"
-- >>> testJSaddle $ strToText <$> (obj >>= valToJSON)
-- {}
valToJSON :: ToJSVal value => value -> JSM JSString
#ifdef ghcjs_HOST_OS
valToJSON value = jsrefToJSON <$> toJSVal value
foreign import javascript unsafe
#if __GLASGOW_HASKELL__ >= 900
"(($1) => { return $1 === undefined ? \"\" : JSON.stringify($1); })"
#else
"$r = $1 === undefined ? \"\" : JSON.stringify($1);"
#endif
jsrefToJSON :: JSVal -> JSString
#else
valToJSON value = toJSVal value >>= valueToJSON
#endif
-- | Given a JavaScript value get its object value.
-- May throw JSException.
--
-- >>> testJSaddle $ (valToObject JSNull >>= valToText) `catch` \ (JSException e) -> valToText e
-- null
-- >>> testJSaddle $ (valToObject () >>= valToText) `catch` \ (JSException e) -> valToText e
-- undefined
-- >>> testJSaddle $ valToObject True
-- true
-- >>> testJSaddle $ valToObject False
-- false
-- >>> testJSaddle $ valToObject (1.0 :: Double)
-- 1
-- >>> testJSaddle $ valToObject (0.0 :: Double)
-- 0
-- >>> testJSaddle $ valToObject ""
-- <BLANKLINE>
-- >>> testJSaddle $ valToObject "1"
-- 1
valToObject :: ToJSVal value => value -> JSM Object
valToObject value = Object <$> toJSVal value
instance MakeObject JSVal where
makeObject = return . Object
instance ToJSVal Object where
toJSVal (Object r) = return r
-- | Convert to a JavaScript value (just an alias for 'toJSVal')
val :: ToJSVal value
=> value -- ^ value to convert to a JavaScript value
-> JSM JSVal
val = toJSVal
#ifndef ghcjs_HOST_OS
-- | If we already have a JSVal we are fine
instance ToJSVal JSVal where
toJSVal = return
{-# INLINE toJSVal #-}
#endif
-- | A single JSVal can be used as the argument list
instance MakeArgs JSVal where
makeArgs arg = return [arg]
-- | JSVal can be made by evaluating a function in 'JSM' as long
-- as it returns something we can make into a JSVal.
instance ToJSVal v => ToJSVal (JSM v) where
toJSVal v = v >>= toJSVal
{-# INLINE toJSVal #-}
----------- null ---------------
-- | A @null@ JavaScript value
valNull :: JSVal
valNull = jsNull
{-# INLINE valNull #-}
-- | Makes a @null@ JavaScript value
instance ToJSVal JSNull where
toJSVal = const (return jsNull)
{-# INLINE toJSVal #-}
-- | Makes an argument list with just a single @null@ JavaScript value
instance MakeArgs JSNull where
makeArgs _ = return [jsNull]
#ifndef ghcjs_HOST_OS
-- | Makes a JSVal or @null@ JavaScript value
instance ToJSVal a => ToJSVal (Maybe a) where
toJSVal Nothing = return jsNull
toJSVal (Just a) = toJSVal a
{-# INLINE toJSVal #-}
instance FromJSVal a => FromJSVal (Maybe a) where
fromJSValUnchecked x =
ghcjsPure (isUndefined x) >>= \case
True -> return Nothing
False -> ghcjsPure (isNull x) >>= \case
True -> return Nothing
False -> fromJSVal x
{-# INLINE fromJSValUnchecked #-}
fromJSVal x =
ghcjsPure (isUndefined x) >>= \case
True -> return (Just Nothing)
False -> ghcjsPure (isNull x) >>= \case
True -> return (Just Nothing)
False -> fmap (fmap Just) fromJSVal x
{-# INLINE fromJSVal #-}
-- Make an array out of various lists
instance ToJSVal a => ToJSVal [a] where
toJSVal = toJSValListOf
{-# INLINE toJSVal #-}
instance FromJSVal a => FromJSVal [a] where
fromJSVal = fromJSValListOf
{-# INLINE fromJSVal #-}
#endif
-- | Test a JavaScript value to see if it is @null@
valIsNull :: ToJSVal value => value -> JSM Bool
valIsNull value = toJSVal value >>= ghcjsPure . isNull
----------- undefined ---------------
-- | An @undefined@ JavaScript value
valUndefined :: JSVal
valUndefined = jsUndefined
{-# INLINE valUndefined #-}
-- | Makes an @undefined@ JavaScript value
instance ToJSVal JSUndefined where
toJSVal = const (return jsUndefined)
--We can't allow this if JSUndefined is () as () is no args not "(null)".
--Use [()] instead.
--instance MakeArgs JSUndefined where
-- makeArgs _ = valMakeUndefined >>= (\ref -> return [ref])
-- | This allows us to pass no arguments easily (altenative would be to use @[]::[JSVal]@).
instance MakeArgs () where
makeArgs _ = return []
-- | Test a JavaScript value to see if it is @undefined@
valIsUndefined :: ToJSVal value => value -> JSM Bool
valIsUndefined value = toJSVal value >>= ghcjsPure . isUndefined
-- | Convert a JSVal to a Maybe JSVal (converting null and undefined to Nothing)
maybeNullOrUndefined :: ToJSVal value => value -> JSM (Maybe JSVal)
maybeNullOrUndefined value = do
rval <- toJSVal value
ghcjsPure (isNull rval) >>= \case
True -> return Nothing
_ ->
ghcjsPure (isUndefined rval) >>= \case
True -> return Nothing
_ -> return (Just rval)
maybeNullOrUndefined' :: ToJSVal value => (JSVal -> JSM a) -> value -> JSM (Maybe a)
maybeNullOrUndefined' f value = do
rval <- toJSVal value
ghcjsPure (isNull rval) >>= \case
True -> return Nothing
_ ->
ghcjsPure (isUndefined rval) >>= \case
True -> return Nothing
_ -> Just <$> f rval
----------- booleans ---------------
-- | A JavaScript boolean value
valBool :: Bool -> JSVal
valBool = toJSBool
{-# INLINE valBool #-}
#ifndef ghcjs_HOST_OS
-- | Make a JavaScript boolean value
instance ToJSVal Bool where
toJSVal = return . valBool
{-# INLINE toJSVal #-}
#endif
-- | Makes an argument list with just a single JavaScript boolean value
instance MakeArgs Bool where
makeArgs b = return [valBool b]
----------- numbers ---------------
-- | Make a JavaScript number
valMakeNumber :: Double -> JSM JSVal
valMakeNumber = toJSVal
{-# INLINE valMakeNumber #-}
#ifndef ghcjs_HOST_OS
-- | Makes a JavaScript number
instance ToJSVal Double where
toJSVal = numberToValue
{-# INLINE toJSVal #-}
instance ToJSVal Float where
toJSVal = numberToValue . realToFrac
{-# INLINE toJSVal #-}
instance ToJSVal Word where
toJSVal = numberToValue . fromIntegral
{-# INLINE toJSVal #-}
instance ToJSVal Word8 where
toJSVal = numberToValue . fromIntegral
{-# INLINE toJSVal #-}
instance ToJSVal Word16 where
toJSVal = numberToValue . fromIntegral
{-# INLINE toJSVal #-}
instance ToJSVal Word32 where
toJSVal = numberToValue . fromIntegral
{-# INLINE toJSVal #-}
instance ToJSVal Int where
toJSVal = numberToValue . fromIntegral
{-# INLINE toJSVal #-}
instance ToJSVal Int8 where
toJSVal = numberToValue . fromIntegral
{-# INLINE toJSVal #-}
instance ToJSVal Int16 where
toJSVal = numberToValue . fromIntegral
{-# INLINE toJSVal #-}
instance ToJSVal Int32 where
toJSVal = numberToValue . fromIntegral
{-# INLINE toJSVal #-}
#endif
-- | Makes an argument list with just a single JavaScript number
instance MakeArgs Double where
makeArgs n = valMakeNumber n >>= (\ref -> return [ref])
-- | Make a JavaScript string from `Text`
valMakeText :: Text -> JSM JSVal
valMakeText = toJSVal . textToJSString
{-# INLINE valMakeText #-}
-- | Make a JavaScript string from `JSString`
valMakeString :: JSString -> JSM JSVal
valMakeString = toJSVal
{-# INLINE valMakeString #-}
#ifndef ghcjs_HOST_OS
-- | Makes a JavaScript string
instance ToJSVal Text where
toJSVal = stringToValue . JSString
{-# INLINE toJSVal #-}
instance FromJSVal Text where
fromJSValUnchecked = valToText
{-# INLINE fromJSValUnchecked #-}
fromJSVal = fmap Just . valToText
{-# INLINE fromJSVal #-}
#endif
-- | Makes an argument list with just a single JavaScript string
instance MakeArgs Text where
makeArgs t = valMakeText t >>= (\ref -> return [ref])
#ifndef ghcjs_HOST_OS
-- | Makes a JavaScript string
instance ToJSVal JSString where
toJSVal = stringToValue
{-# INLINE toJSVal #-}
instance FromJSVal JSString where
fromJSValUnchecked = valToStr
{-# INLINE fromJSValUnchecked #-}
fromJSVal = fmap Just . valToStr
{-# INLINE fromJSVal #-}
#endif
-- | If we already have a JSString we are fine
instance ToJSString JSString where
toJSString = id
instance ToJSString Text where
toJSString = textToStr
instance ToJSString String where
toJSString = textToStr . T.pack
instance FromJSString Text where
fromJSString = strToText
instance FromJSString String where
fromJSString v = T.unpack $ strToText v
instance FromJSString JSString where
fromJSString = id
#ifndef ghcjs_HOST_OS
instance ToJSVal Char where
toJSVal = valMakeNumber . fromIntegral . ord
{-# INLINE toJSVal #-}
toJSValListOf = valMakeText . T.pack
{-# INLINE toJSValListOf #-}
instance FromJSVal Char where
fromJSValUnchecked = fmap (chr . round) . valToNumber
{-# INLINE fromJSValUnchecked #-}
fromJSVal = fmap (Just . chr . round) . valToNumber
{-# INLINE fromJSVal #-}
fromJSValUncheckedListOf = fmap (T.unpack . strToText) . valToStr
{-# INLINE fromJSValListOf #-}
fromJSValListOf = fmap (Just . T.unpack . strToText) . valToStr
{-# INLINE fromJSValUncheckedListOf #-}
#endif
-- | Make a JavaScript string from AESON `Value`
valMakeJSON :: Value -> JSM JSVal
valMakeJSON = toJSVal
#ifndef ghcjs_HOST_OS
-- | Makes a JSON value
instance ToJSVal Value where
toJSVal = jsonValueToValue
{-# INLINE toJSVal #-}
#endif
-- | Makes an argument list with just a single JSON value
instance MakeArgs Value where
makeArgs t = valMakeJSON t >>= (\ref -> return [ref])
-- | Derefernce a value reference.
--
-- >>> testJSaddle $ showJSValue <$> deRefVal JSNull
-- null
-- >>> testJSaddle $ showJSValue <$> deRefVal ()
-- undefined
-- >>> testJSaddle $ showJSValue <$> deRefVal True
-- true
-- >>> testJSaddle $ showJSValue <$> deRefVal False
-- false
-- >>> testJSaddle $ showJSValue <$> deRefVal (1.0 :: Double)
-- 1.0
-- >>> testJSaddle $ showJSValue <$> deRefVal (0.0 :: Double)
-- 0.0
-- >>> testJSaddle $ showJSValue <$> deRefVal ""
-- ""
-- >>> testJSaddle $ showJSValue <$> deRefVal "1"
-- "1"
-- >>> testJSaddle $ showJSValue <$> (valToObject True >>= deRefVal)
-- true
-- >>> testJSaddle $ showJSValue <$> (obj >>= deRefVal)
-- object
deRefVal :: ToJSVal value => value -> JSM JSValue
#ifdef ghcjs_HOST_OS
deRefVal value = do
valref <- toJSVal value
case (jsrefGetType valref :: Int) of
0 -> return ValUndefined
1 -> return ValNull
2 -> ValBool <$> valToBool valref
3 -> ValNumber <$> valToNumber valref
4 -> ValString <$> valToText valref
5 -> ValObject <$> valToObject valref
_ -> error "Unexpected result dereferencing JSaddle value"
foreign import javascript unsafe
#if __GLASGOW_HASKELL__ >= 900
"(($1) => { return ($1 === undefined)?0:\
($1===null)?1:\
(typeof $1===\"boolean\")?2:\
(typeof $1===\"number\")?3:\
(typeof $1===\"string\")?4:\
(typeof $1===\"object\")?5:-1; })"
#else
"$r = ($1 === undefined)?0:\
($1===null)?1:\
(typeof $1===\"boolean\")?2:\
(typeof $1===\"number\")?3:\
(typeof $1===\"string\")?4:\
(typeof $1===\"object\")?5:-1;"
#endif
jsrefGetType :: JSVal -> Int
#else
deRefVal value = do
v <- toJSVal value
result <- N.deRefVal v
return $ case result of
DeRefValResult 0 _ -> ValNull
DeRefValResult 1 _ -> ValUndefined
DeRefValResult 2 _ -> ValBool False
DeRefValResult 3 _ -> ValBool True
DeRefValResult (-1) s -> ValNumber (read (T.unpack s))
DeRefValResult (-2) s -> ValString s
DeRefValResult (-3) _ -> ValObject (Object v)
_ -> error "Unexpected result dereferencing JSaddle value"
#endif
-- | Make a JavaScript value out of a 'JSValue' ADT.
--
-- >>> testJSaddle $ valMakeRef ValNull
-- null
-- >>> testJSaddle $ valMakeRef ValUndefined
-- undefined
-- >>> testJSaddle $ valMakeRef (ValBool True)
-- true
-- >>> testJSaddle $ valMakeRef (ValNumber 1)
-- 1
-- >>> testJSaddle $ valMakeRef (ValString $ T.pack "Hello")
-- Hello
valMakeRef :: JSValue -> JSM JSVal
valMakeRef value =
case value of
ValNull -> return valNull
ValUndefined -> return valUndefined
ValBool b -> return $ valBool b
ValNumber n -> valMakeNumber n
ValString s -> valMakeText s
ValObject (Object o) -> return o
-- | Makes a JavaScript value from a 'JSValue' ADT.
instance ToJSVal JSValue where
toJSVal = valMakeRef
{-# INLINE toJSVal #-}
-- | Makes an argument list with just a single JavaScript value from a 'JSValue' ADT.
instance MakeArgs JSValue where
makeArgs v = valMakeRef v >>= (\ref -> return [ref])
--instance MakeObjectRef JSNull where
-- makeObjectRef _ = Object <$> valMakeNull
-- {-# INLINE makeObjectRef #-}
#ifdef ghcjs_HOST_OS
foreign import javascript unsafe
#if __GLASGOW_HASKELL__ >= 900
"(($1,$2) => { return $1===$2; })"
#else
"$1===$2"
#endif
jsvalueisstrictequal :: JSVal -> JSVal -> Bool
#endif
-- | Determine if two values are equal (JavaScripts ===)
-- >>> testJSaddle $ strictEqual True False
-- false
-- >>> testJSaddle $ strictEqual True True
-- true
-- >>> testJSaddle $ strictEqual "Hello" ()
-- false
-- >>> testJSaddle $ strictEqual "Hello" "Hello"
-- true
strictEqual :: (ToJSVal a, ToJSVal b) => a -> b -> JSM Bool
strictEqual a b = do
aval <- toJSVal a
bval <- toJSVal b
#ifdef ghcjs_HOST_OS
return $ jsvalueisstrictequal aval bval
#else
N.strictEqual aval bval
#endif
#ifdef ghcjs_HOST_OS
foreign import javascript unsafe
#if __GLASGOW_HASKELL__ >= 900
"(($1,$2) => { return $1 instanceof $2; })"
#else
"$1 instanceof $2"
#endif
js_isInstanceOf :: JSVal -> Object -> Bool
#endif
-- | Determine if two values are equal (JavaScripts ===)
-- >>> testJSaddle $ instanceOf obj (Object <$> jsg "Object")
-- true
instanceOf :: (ToJSVal value, MakeObject constructor) => value -> constructor -> JSM Bool
instanceOf value constructor = do
v <- toJSVal value
c <- makeObject constructor
#ifdef ghcjs_HOST_OS
return $ js_isInstanceOf v c
#else
N.instanceOf v c
#endif