haste-compiler- Haskell To ECMAScript compiler

Safe HaskellNone




High level JavaScript foreign interface.


Conversion to/from JSAny

class ToAny a where Source

Any type that can be converted into a JavaScript value.

Minimal complete definition



toAny :: a -> JSAny Source

Build a JS object from a Haskell value.

The default instance creates an object from any type that derives Generic according to the following rules:

  • Records turn into plain JS objects, with record names as field names.
  • Non-record product types turn into objects containing a $data field which contains all of the constructor's unnamed fields.
  • Values of enum types turn into strings matching their constructors.
  • Non-enum types with more than one constructor gain an extra field, $tag, which contains the name of the constructor used to create the object.

listToAny :: [a] -> JSAny Source


ToAny Bool Source 
ToAny Char Source 
ToAny Double Source 
ToAny Float Source 
ToAny Int Source 
ToAny Int8 Source 
ToAny Int16 Source 
ToAny Int32 Source 
ToAny Word Source 
ToAny Word8 Source 
ToAny Word16 Source 
ToAny Word32 Source 
ToAny () Source 
ToAny JSString Source 
ToAny JSAny Source 
ToAny RegEx Source 
ToAny Method Source 
ToAny Elem Source 
ToAny Blob Source 
ToAny BlobData Source 
ToAny FrameRequest Source 
ToAny Canvas Source 
ToAny Ctx Source 
ToAny Bitmap Source 
ToAny WebSocket Source 
ToAny a => ToAny [a] Source

Lists are marshalled into arrays, with the exception of String.

ToAny (Ptr a) Source 
ToAny a => ToAny (Maybe a) Source

Maybe is simply a nullable type. Nothing is equivalent to null, and any non-null value is equivalent to x in Just x.

ToAny (Opaque a) Source 
(ToAny a, ToAny b) => ToAny (a, b) Source

Tuples are marshalled into arrays.

(ToAny a, ToAny b, ToAny c) => ToAny (a, b, c) Source 
(ToAny a, ToAny b, ToAny c, ToAny d) => ToAny (a, b, c, d) Source 
(ToAny a, ToAny b, ToAny c, ToAny d, ToAny e) => ToAny (a, b, c, d, e) Source 
(ToAny a, ToAny b, ToAny c, ToAny d, ToAny e, ToAny f) => ToAny (a, b, c, d, e, f) Source 
(ToAny a, ToAny b, ToAny c, ToAny d, ToAny e, ToAny f, ToAny g) => ToAny (a, b, c, d, e, f, g) Source 

class FromAny a where Source

Any type that can be converted from a JavaScript value.

Minimal complete definition



fromAny :: JSAny -> IO a Source

Convert a value from JS with a reasonable conversion if an exact match is not possible. Examples of reasonable conversions would be truncating floating point numbers to integers, or turning signed integers into unsigned.

The default instance is the inverse of the default ToAny instance.

listFromAny :: JSAny -> IO [a] Source

data JSAny Source

Any JS value, with one layer of indirection.

data Opaque a Source

The Opaque type is inhabited by values that can be passed to JavaScript using their raw Haskell representation. Opaque values are completely useless to JS code, and should not be inspected. This is useful for, for instance, storing data in some JS-native data structure for later retrieval.


nullValue :: JSAny Source

The JS value null.

toObject :: [(JSString, JSAny)] -> JSAny Source

Build a new JS object from a list of key:value pairs.

has :: JSAny -> JSString -> IO Bool Source

Check if a JS object has a particular member.

get :: FromAny a => JSAny -> JSString -> IO a Source

Read a member from a JS object. Throws an error if the member can not be marshalled into a value of type a.

index :: FromAny a => JSAny -> Int -> IO a Source

Read an element from a JS array. Throws an error if the member can not be marshalled into a value of type a.

getMaybe :: FromAny a => JSAny -> JSString -> IO (Maybe a) Source

Read a member from a JS object. Succeeds if the member exists.

hasAll :: JSAny -> [JSString] -> IO Bool Source

Checks if a JS object has a list of members. Succeeds if the JS object has every member given in the list.

lookupAny :: JSAny -> JSString -> IO (Maybe JSAny) Source

Looks up an object by a .-separated string. Succeeds if the lowest member exists.

Usage example:

>>> {'child': {'childrer': {'childerest': "I am very much a child."}}}

Given the JS Object above, we can access the deeply nested object, childerest, by lookupAny as in the below example

>>> lookupAny jsObject "child.childrer.childerest"

Importing and exporting JavaScript functions

class FFI a Source

Any type that can be imported from JavaScript. This means any type which has an instance of FromAny, and any function where all argument types has ToAny instances and the return type is in the IO monad and has a FromAny instance.


FromAny a => FFI (IO a) Source 
(ToAny a, FFI b) => FFI (a -> b) Source 

class JSFunc a Source

Minimal complete definition

mkJSFunc, arity


(ToAny a, (~) * (JS a) JSAny) => JSFunc a Source 
ToAny a => JSFunc (IO a) Source 
(FromAny a, JSFunc b) => JSFunc (a -> b) Source 

ffi :: FFI a => JSString -> a Source

Creates a Haskell function from the given string of JavaScript code. If this code is not well typed or is otherwise incorrect, your program may crash or misbehave in mystifying ways. Haste makes a best-effort try to save you from poorly typed JS here, but there are no guarantees.

For instance, the following WILL cause crazy behavior due to wrong types:

ffi "(function(x) {return x+1;})" :: Int -> Int -> IO Int

In other words, this function is as unsafe as the JS it calls on. You have been warned.

The imported JS is evaluated lazily, unless (a) it is a function object in which case evaluation order does not affect the semantics of the imported code, or if (b) the imported code is explicitly marked as strict:

someFunction = ffi "__strict(someJSFunction)"

Literals which depends on some third party initialization, the existence of a DOM tree or some other condition which is not fulfilled at load time should *not* be marked strict.

constant :: FromAny a => JSString -> a Source

Create a Haskell value from a constant JS expression.

export :: ToAny a => JSString -> a -> IO () Source

Export a symbol. That symbol may then be accessed from JavaScript through Haste.name() as a normal function. Remember, however, that if you are using --with-js to include your JS, in conjunction with --opt-minify or any option that implies it, you will instead need to access your exports through Haste['name'](), or Closure will mangle your function names.

data StaticPtr a :: * -> *

A reference to a value of type a.