3

I am surprised to know that Aeson encodes () as empty array. What is reason behind such behaviour? I think null would be more natural, am I wrong?

*Main> encode ()
"[]"
lambdas
  • 3,990
  • 2
  • 29
  • 54

1 Answers1

7

The ToJSON instance for () is defined as:

instance ToJSON () where
    toJSON _ = emptyArray
    {-# INLINE toJSON #-}

Because generally, tuples are encoded as arrays:

instance (ToJSON a, ToJSON b) => ToJSON (a,b) where
    toJSON (a,b) = Array $ V.create $ do
                     mv <- VM.unsafeNew 2
                     VM.unsafeWrite mv 0 (toJSON a)
                     VM.unsafeWrite mv 1 (toJSON b)
                     return mv

(I think null doesn't make much sense; usually null represents a lack of value where there could be one, so in Haskell you'd use Nothing. In fact, encode Nothing returns "null". () is just a 0-tuple, and this instance is more consistent with other tuples.)

Lynn
  • 10,425
  • 43
  • 75
  • The problem with `Nothing` is that you should specify meaningless type, you can't just write `Nothing`. I.e. `encode (Nothing :: Maybe Text)`. Thank you, it does make sense now. – lambdas Oct 21 '13 at 03:41
  • 1
    Isn't it idiomatic to use `()` to represent lack of value, like in `IO ()`? – lambdas Oct 21 '13 at 03:46
  • 1
    @lambdas Strictly speaking that's "lack of information", not "lack of a value". `()` is the type that contains only the single value `()`; thus it's the type of values that "contain no information". Thus `IO ()` is the type of I/O actions that when run *must* produce "no information" as a value (only relevant for their side effects). There is a type `Void` in a library that *doesn't have any values*. But `IO Void` would be the type of I/O actions that cannot succeed in finishing and producing a value (if they did, they would produce a value in the type `Void`, but there are no such values). – Ben Oct 21 '13 at 05:47
  • 1
    You actually couldn't! See, `Void` has *no* values at all. A function of type `Void -> a` can't return anything, because there's nothing you can pass it. – Lynn Oct 21 '13 at 16:11
  • It is possible, if we don't care of `Void` argument and return `undefined`, but then it is easy to forgot this, use returned value and crash the program. I'll better not do so. – lambdas Oct 22 '13 at 03:13
  • I mean it is possible to write `ToJSON _ = Null` and `FromJSON Null = undefined`. – lambdas Oct 22 '13 at 03:15