{-#LANGUAGE NoImplicitPrelude #-} {-#LANGUAGE GeneralizedNewtypeDeriving #-} {-#LANGUAGE FlexibleInstances #-} {-#LANGUAGE MultiParamTypeClasses #-} {-#LANGUAGE DeriveFunctor #-} module Data.AList ( AList , toList , fromList , empty , singleton ) where import ClassyPrelude hiding (fromList, toList, singleton, empty) import Data.Aeson (ToJSON (..), FromJSON (..), Value (..)) import qualified Data.HashMap.Strict as HashMap import Data.Monoid import Data.Text (Text) import qualified Data.Vector as Vector import Control.Monad (forM) newtype AList k v = AList { toList :: [(k, v)] } deriving (Functor, Monoid, Show, Read, Eq, Semigroup) fromList :: [(k, v)] -> AList k v fromList = AList instance FromJSON a => FromJSON (AList Text a) where parseJSON (Array items) = mconcat <$> forM (Vector.toList items) parseJSON parseJSON v@(Object obj) = AList . HashMap.toList <$> parseJSON v parseJSON x = fail "Invalid JSON value for AList" instance ToJSON a => ToJSON (AList Text a) where toJSON (AList items) = toJSON [ HashMap.singleton k v | (k, v) <- items ] empty :: AList k v empty = AList [] singleton :: k -> v -> AList k v singleton k v = AList [(k, v)]