| 1 |
{-# LANGUAGE DataKinds #-}
|
| 2 |
{-# LANGUAGE DefaultSignatures #-}
|
| 3 |
{-# LANGUAGE FlexibleContexts #-}
|
| 4 |
{-# LANGUAGE FlexibleInstances #-}
|
| 5 |
{-# LANGUAGE GADTs #-}
|
| 6 |
{-# LANGUAGE OverloadedLists #-}
|
1 | 7 |
{-# LANGUAGE OverloadedStrings #-}
|
2 | |
{-# LANGUAGE OverloadedLists #-}
|
| 8 |
{-# LANGUAGE ScopedTypeVariables #-}
|
| 9 |
{-# LANGUAGE TypeOperators #-}
|
3 | 10 |
{-# LANGUAGE TypeSynonymInstances #-}
|
4 | |
{-# LANGUAGE FlexibleInstances #-}
|
5 | |
{-# LANGUAGE FlexibleContexts #-}
|
6 | |
{-# LANGUAGE TypeOperators #-}
|
7 | |
{-# LANGUAGE ScopedTypeVariables #-}
|
8 | |
{-# LANGUAGE DefaultSignatures #-}
|
9 | |
{-# LANGUAGE DataKinds #-}
|
10 | |
{-# LANGUAGE GADTs #-}
|
11 | 11 |
|
12 | 12 |
module Data.Adnot.Class where
|
13 | 13 |
|
14 | |
import Control.Monad ((>=>))
|
15 | |
import Data.Adnot.Parse
|
16 | |
import Data.Adnot.Type
|
17 | |
import Data.Adnot.Emit
|
18 | |
import Data.Adnot.Parse
|
19 | |
import Data.Int
|
20 | |
import Data.Word
|
| 14 |
import Control.Monad ((>=>))
|
| 15 |
import Data.Adnot.Emit
|
| 16 |
import Data.Adnot.Parse
|
| 17 |
import Data.Adnot.Type
|
21 | 18 |
import qualified Data.ByteString as BS
|
22 | 19 |
import qualified Data.ByteString.Lazy as BSL
|
23 | 20 |
import qualified Data.Foldable as F
|
| 21 |
import Data.Int
|
24 | 22 |
import qualified Data.List.NonEmpty as NE
|
25 | 23 |
import qualified Data.Map.Lazy as ML
|
26 | 24 |
import qualified Data.Map.Strict as MS
|
|
28 | 26 |
import qualified Data.Text as T
|
29 | 27 |
import qualified Data.Text.Lazy as TL
|
30 | 28 |
import qualified Data.Vector as V
|
31 | |
import GHC.Generics
|
32 | |
import GHC.TypeLits (KnownSymbol)
|
| 29 |
import Data.Word
|
| 30 |
import GHC.Generics
|
| 31 |
import GHC.TypeLits (KnownSymbol)
|
33 | 32 |
|
34 | 33 |
encode :: ToAdnot a => a -> BSL.ByteString
|
35 | 34 |
encode = encodeValue . toAdnot
|
|
46 | 45 |
|
47 | 46 |
instance (GatherSequence f, Constructor name) => GenToAdnot (C1 name f) where
|
48 | 47 |
genToAdnot (M1 x) = Sum (T.pack (conName c)) (V.fromList (gatherSequence x))
|
49 | |
where c :: M1 c name f ()
|
50 | |
c = undefined
|
| 48 |
where
|
| 49 |
c :: M1 c name f ()
|
| 50 |
c = undefined
|
51 | 51 |
|
52 | 52 |
instance (GenToAdnot f) => GenToAdnot (S1 name f) where
|
53 | 53 |
genToAdnot (M1 x) = genToAdnot x
|
|
66 | 66 |
|
67 | 67 |
instance (GenToAdnot f, Selector name) => GatherRecord (S1 name f) where
|
68 | 68 |
gatherRecord (M1 x) = [(T.pack (selName s), genToAdnot x)]
|
69 | |
where s :: S1 name f ()
|
70 | |
s = undefined
|
| 69 |
where
|
| 70 |
s :: S1 name f ()
|
| 71 |
s = undefined
|
71 | 72 |
|
72 | 73 |
instance GatherRecord U1 where
|
73 | 74 |
gatherRecord U1 = []
|
|
98 | 99 |
|
99 | 100 |
class ToAdnot a where
|
100 | 101 |
toAdnot :: a -> Value
|
101 | |
|
102 | 102 |
default toAdnot :: (Generic a, GenToAdnot (Rep a)) => a -> Value
|
103 | 103 |
toAdnot = genericToAdnot
|
104 | 104 |
|
|
180 | 180 |
key .= val = (key, toAdnot val)
|
181 | 181 |
|
182 | 182 |
-- * Tuples
|
| 183 |
|
183 | 184 |
instance ToAdnot () where
|
184 | 185 |
toAdnot () = List []
|
185 | 186 |
|
|
189 | 190 |
instance (ToAdnot a, ToAdnot b, ToAdnot c) => ToAdnot (a, b, c) where
|
190 | 191 |
toAdnot (a, b, c) = List [toAdnot a, toAdnot b, toAdnot c]
|
191 | 192 |
|
192 | |
instance (ToAdnot a, ToAdnot b, ToAdnot c, ToAdnot d)
|
193 | |
=> ToAdnot (a, b, c, d) where
|
| 193 |
instance
|
| 194 |
(ToAdnot a, ToAdnot b, ToAdnot c, ToAdnot d) =>
|
| 195 |
ToAdnot (a, b, c, d)
|
| 196 |
where
|
194 | 197 |
toAdnot (a, b, c, d) = List [toAdnot a, toAdnot b, toAdnot c, toAdnot d]
|
195 | 198 |
|
196 | 199 |
-- Common Haskell algebraic data types
|
|
199 | 202 |
toAdnot (Just x) = Sum "Just" [toAdnot x]
|
200 | 203 |
|
201 | 204 |
instance (ToAdnot a, ToAdnot b) => ToAdnot (Either a b) where
|
202 | |
toAdnot (Left x) = Sum "Left" [toAdnot x]
|
| 205 |
toAdnot (Left x) = Sum "Left" [toAdnot x]
|
203 | 206 |
toAdnot (Right y) = Sum "Right" [toAdnot y]
|
204 | 207 |
|
205 | 208 |
instance ToAdnot Bool where
|
206 | |
toAdnot True = String "True"
|
| 209 |
toAdnot True = String "True"
|
207 | 210 |
toAdnot False = String "False"
|
208 | 211 |
|
209 | 212 |
-- Parsing
|
|
212 | 215 |
decode = decodeValue >=> parseAdnot
|
213 | 216 |
|
214 | 217 |
type ParseError = String
|
| 218 |
|
215 | 219 |
type Parser a = Either ParseError a
|
216 | 220 |
|
217 | 221 |
niceType :: Value -> String
|
218 | |
niceType Sum {} = "sum"
|
| 222 |
niceType Sum {} = "sum"
|
219 | 223 |
niceType Product {} = "product"
|
220 | |
niceType List {} = "list"
|
| 224 |
niceType List {} = "list"
|
221 | 225 |
niceType Integer {} = "integer"
|
222 | |
niceType Double {} = "double"
|
223 | |
niceType String {} = "string"
|
| 226 |
niceType Double {} = "double"
|
| 227 |
niceType String {} = "string"
|
224 | 228 |
|
225 | 229 |
withSum :: String -> (T.Text -> Array -> Parser a) -> Value -> Parser a
|
226 | 230 |
withSum n k val = case val of
|
227 | 231 |
Sum t as -> k t as
|
228 | |
_ -> Left ("Expected sum in " ++ n)
|
| 232 |
_ -> Left ("Expected sum in " ++ n)
|
229 | 233 |
|
230 | 234 |
withSumNamed :: String -> T.Text -> (Array -> Parser a) -> Value -> Parser a
|
231 | 235 |
withSumNamed n tag k val = case val of
|
232 | 236 |
Sum t as
|
233 | 237 |
| tag == t -> k as
|
234 | |
| otherwise -> Left $ unwords
|
235 | |
[ "Expected tag", T.unpack tag, "in", n, "but found", T.unpack t ]
|
236 | |
_ -> Left ("Expected sum in " ++ n)
|
| 238 |
| otherwise ->
|
| 239 |
Left $
|
| 240 |
unwords
|
| 241 |
["Expected tag", T.unpack tag, "in", n, "but found", T.unpack t]
|
| 242 |
_ -> Left ("Expected sum in " ++ n)
|
237 | 243 |
|
238 | 244 |
withProduct :: String -> (Product -> Parser a) -> Value -> Parser a
|
239 | 245 |
withProduct n k val = case val of
|
240 | 246 |
Product ps -> k ps
|
241 | |
_ -> Left ("Expected product in " ++ n)
|
| 247 |
_ -> Left ("Expected product in " ++ n)
|
242 | 248 |
|
243 | 249 |
withList :: String -> (Array -> Parser a) -> Value -> Parser a
|
244 | 250 |
withList n k val = case val of
|
245 | 251 |
List ls -> k ls
|
246 | |
_ -> Left ("Expected list in " ++ n)
|
| 252 |
_ -> Left ("Expected list in " ++ n)
|
247 | 253 |
|
248 | 254 |
withInteger :: String -> (Integer -> Parser a) -> Value -> Parser a
|
249 | 255 |
withInteger n k val = case val of
|
250 | 256 |
Integer i -> k i
|
251 | |
_ -> Left ("Expected integer in " ++ n)
|
| 257 |
_ -> Left ("Expected integer in " ++ n)
|
252 | 258 |
|
253 | 259 |
withDouble :: String -> (Double -> Parser a) -> Value -> Parser a
|
254 | 260 |
withDouble n k val = case val of
|
255 | |
Double d -> k d
|
| 261 |
Double d -> k d
|
256 | 262 |
Integer i -> k (fromIntegral i)
|
257 | |
_ -> Left ("Expected double in " ++ n)
|
| 263 |
_ -> Left ("Expected double in " ++ n)
|
258 | 264 |
|
259 | 265 |
withString :: String -> (T.Text -> Parser a) -> Value -> Parser a
|
260 | 266 |
withString n k val = case val of
|
261 | 267 |
String s -> k s
|
262 | |
_ -> Left ("Expected string in " ++ n)
|
| 268 |
_ -> Left ("Expected string in " ++ n)
|
263 | 269 |
|
264 | 270 |
(.:) :: FromAdnot a => Product -> T.Text -> Parser a
|
265 | 271 |
map .: key = case MS.lookup key map of
|
266 | |
Just x -> parseAdnot x
|
| 272 |
Just x -> parseAdnot x
|
267 | 273 |
Nothing -> Left ("Missing key " ++ show key)
|
268 | 274 |
|
269 | 275 |
(.:?) :: FromAdnot a => Product -> T.Text -> Parser (Maybe a)
|
270 | 276 |
map .:? key = case MS.lookup key map of
|
271 | |
Just x -> Just <$> parseAdnot x
|
| 277 |
Just x -> Just <$> parseAdnot x
|
272 | 278 |
Nothing -> return Nothing
|
273 | 279 |
|
274 | 280 |
(.!=) :: Parser (Maybe a) -> a -> Parser a
|
|
332 | 338 |
parseAdnot = withString "Text" return
|
333 | 339 |
|
334 | 340 |
instance FromAdnot TL.Text where
|
335 | |
parseAdnot = withString "Text" (return . TL.fromStrict)
|
| 341 |
parseAdnot = withString "Text" (return . TL.fromStrict)
|
336 | 342 |
|
337 | 343 |
instance FromAdnot Char where
|
338 | 344 |
parseAdnot = withString "Char" $ \s -> case T.uncons s of
|
339 | 345 |
Just (c, "") -> return c
|
340 | |
_ -> Left "Expected a single-element string"
|
341 | |
|
| 346 |
_ -> Left "Expected a single-element string"
|
342 | 347 |
|
343 | 348 |
-- List types
|
344 | 349 |
instance FromAdnot a => FromAdnot [a] where
|
|
358 | 363 |
lst <- mapM parseAdnot ls
|
359 | 364 |
case F.toList lst of
|
360 | 365 |
[] -> Left "Expected non-empty sequence"
|
361 | |
(x:xs) -> Right (x NE.:| xs)
|
| 366 |
(x : xs) -> Right (x NE.:| xs)
|
362 | 367 |
|
363 | 368 |
-- Mapping types
|
364 | 369 |
instance FromAdnot a => FromAdnot (MS.Map T.Text a) where
|
|
371 | 376 |
parseAdnot = withList "()" $ \ls ->
|
372 | 377 |
case ls of
|
373 | 378 |
[] -> return ()
|
374 | |
_ -> Left "Expected empty list"
|
| 379 |
_ -> Left "Expected empty list"
|
375 | 380 |
|
376 | 381 |
instance (FromAdnot a, FromAdnot b) => FromAdnot (a, b) where
|
377 | 382 |
parseAdnot = withList "(a, b)" $ \ls ->
|
378 | 383 |
case ls of
|
379 | 384 |
[a, b] -> (,) <$> parseAdnot a <*> parseAdnot b
|
380 | |
_ -> Left "Expected two-element list"
|
381 | |
|
| 385 |
_ -> Left "Expected two-element list"
|
382 | 386 |
|
383 | 387 |
instance (FromAdnot a, FromAdnot b, FromAdnot c) => FromAdnot (a, b, c) where
|
384 | 388 |
parseAdnot = withList "(a, b, c)" $ \ls ->
|
385 | 389 |
case ls of
|
386 | 390 |
[a, b, c] -> (,,) <$> parseAdnot a <*> parseAdnot b <*> parseAdnot c
|
387 | |
_ -> Left "Expected three-element list"
|
388 | |
|
389 | |
|
390 | |
instance (FromAdnot a, FromAdnot b, FromAdnot c, FromAdnot d)
|
391 | |
=> FromAdnot (a, b, c, d) where
|
| 391 |
_ -> Left "Expected three-element list"
|
| 392 |
|
| 393 |
instance
|
| 394 |
(FromAdnot a, FromAdnot b, FromAdnot c, FromAdnot d) =>
|
| 395 |
FromAdnot (a, b, c, d)
|
| 396 |
where
|
392 | 397 |
parseAdnot = withList "(a, b, c, d)" $ \ls ->
|
393 | 398 |
case ls of
|
394 | |
[a, b, c, d] -> (,,,) <$> parseAdnot a <*> parseAdnot b
|
395 | |
<*> parseAdnot c <*> parseAdnot d
|
396 | |
_ -> Left "Expected four-element list"
|
| 399 |
[a, b, c, d] ->
|
| 400 |
(,,,) <$> parseAdnot a <*> parseAdnot b
|
| 401 |
<*> parseAdnot c
|
| 402 |
<*> parseAdnot d
|
| 403 |
_ -> Left "Expected four-element list"
|
397 | 404 |
|
398 | 405 |
-- Common Haskell algebraic data types
|
399 | 406 |
instance FromAdnot a => FromAdnot (Maybe a) where
|
400 | 407 |
parseAdnot = withSum "Maybe" go
|
401 | |
where go "Nothing" [] = return Nothing
|
402 | |
go "Just" [x] = Just <$> parseAdnot x
|
403 | |
go _ _ = Left "Invalid Maybe"
|
| 408 |
where
|
| 409 |
go "Nothing" [] = return Nothing
|
| 410 |
go "Just" [x] = Just <$> parseAdnot x
|
| 411 |
go _ _ = Left "Invalid Maybe"
|
404 | 412 |
|
405 | 413 |
instance (FromAdnot a, FromAdnot b) => FromAdnot (Either a b) where
|
406 | 414 |
parseAdnot = withSum "Either" go
|
407 | |
where go "Left" [x] = Left <$> parseAdnot x
|
408 | |
go "Right" [x] = Right <$> parseAdnot x
|
409 | |
go _ _ = Left "Invalid Either"
|
| 415 |
where
|
| 416 |
go "Left" [x] = Left <$> parseAdnot x
|
| 417 |
go "Right" [x] = Right <$> parseAdnot x
|
| 418 |
go _ _ = Left "Invalid Either"
|
410 | 419 |
|
411 | 420 |
instance FromAdnot Bool where
|
412 | 421 |
parseAdnot = withString "Bool" go
|
413 | |
where go "True" = return True
|
414 | |
go "False" = return False
|
415 | |
go _ = Left "Invalid Bool"
|
| 422 |
where
|
| 423 |
go "True" = return True
|
| 424 |
go "False" = return False
|
| 425 |
go _ = Left "Invalid Bool"
|