Почему Aeson кодирует () как пустой массив?

Я удивлен, узнав, что Эсон кодирует () как пустой массив. В чем причина такого поведения? Я думаю, что null было бы более естественным, я ошибаюсь?

*Main> encode ()
"[]"

person lambdas    schedule 20.10.2013    source источник
comment
Кодирует ли он кортежи как массивы?   -  person zch    schedule 20.10.2013
comment
Да. Возможно, теперь я понимаю.   -  person lambdas    schedule 20.10.2013


Ответы (1)


Экземпляр ToJSON для () определяется как:

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

Потому что обычно кортежи кодируются как массивы:

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

(Я думаю, что null не имеет особого смысла; обычно null означает отсутствие значения там, где оно могло быть, поэтому в Haskell вы должны использовать Nothing. Фактически, encode Nothing возвращает "null". () просто 0-кортеж, и этот экземпляр более совместим с другими кортежами.)

person Lynn    schedule 20.10.2013
comment
Проблема с Nothing в том, что вы должны указать бессмысленный тип, вы не можете просто написать Nothing. т.е. encode (Nothing :: Maybe Text). Спасибо, теперь это имеет смысл. - person lambdas; 21.10.2013
comment
Разве не идиоматично использовать () для обозначения отсутствия ценности, как в IO ()? - person lambdas; 21.10.2013
comment
@lambdas Строго говоря, это отсутствие информации, а не отсутствие ценности. () — это тип, который содержит только одно значение (); таким образом, это тип значений, которые не содержат информации. Таким образом, IO () — это тип действий ввода-вывода, которые при выполнении должны не выдавать никакой информации в качестве значения (относится только к их побочным эффектам). В библиотеке есть тип Void, который не имеет значений. Но IO Void будет типом действий ввода-вывода, которые не могут успешно закончить и создать значение (если бы они это сделали, они создали бы значение типа Void, но таких значений нет). - person Ben; 21.10.2013
comment
Вы на самом деле не могли! Видите ли, Void вообще не имеет никаких значений. Функция типа Void -> a ничего не может вернуть, потому что ей нечего передать. - person Lynn; 21.10.2013
comment
Можно, если не обращать внимания на аргумент Void и возвращать undefined, но тогда об этом легко забыть, использовать возвращаемое значение и вылететь из программы. Я лучше не буду этого делать. - person lambdas; 22.10.2013
comment
Я имею в виду, что можно написать ToJSON _ = Null и FromJSON Null = undefined. - person lambdas; 22.10.2013