Search code examples
purescript

Why is Unit in PureScript's Prelude {} in JavaScript?


I'm a beginner to FP and Type-level programming. I learned Void and Unit recently.

Prelude's unit is defined as {} in JavaScript.

"use strict";

exports.unit = {};

My question is "Why not null but {}?" Maybe this is a trivial question, but I'd like to learn its philosophy.

From my understanding, unit corresponds to null in JavaScript. For example, I can call a function with no arguments in JavaScript.

// hello :: Void -> String
function hello () {
  return "hello"
}

const h1 = hello() // "hello"
// However, I do not have any members of `Void` in PureScript, so I cannot call like above.

If I have to specify some arguments of hello function, I choose null rather than {}.

// hello :: forall a. a -> String
function hello (a) {
  return "hello"
}

// 'hello :: Unit -> String'-like
const h1 = hello(null) // "hello"

// undefined also works, but weird to me
const h2 = hello(undefined)

// also works, but weird
const h3 = hello(42)
const h4 = hello({})
const h5 = hello([])

If unit represents a side-effect, probably is it undefined or something null?

// 'log1 :: String -> Effect Void'-like
function log1 (s) {
  return s => () => console.log(s) // console.log return undefined
}
// however, function must return a value


// 'log2 :: String -> Effect Unit'-like
function log2 (s) {
  return s => () => {
    console.log(s) // side-effect
    return null
  }
}

// foreign Effect.Console.log (ECMAScript-style)
function log3 (s) {
  return s => () => {
    console.log(s)
    return {} // weird to me; it seems like 'return 42'
  }
}

Am I missing something?


Solution

  • It doesn't actually matter what value you use for Unit. {} is a pretty arbitrary choice - undefined or null, or just not returning a value are all fine too if you're writing something in the FFI. Since Unit is only supposed to have one inhabitant, there's never a time that the actual runtime value for it is examined.

    It's quite a long time since the choice of {} was made - it's probably a historical accident, leftover from the time that all non-Prim PS values were constructed as anonymous objects.