@@ -1,59 +1,65 @@
1{-# LANGUAGE AllowAmbiguousTypes #-}
1{-# LANGUAGE AllowAmbiguousTypes #-}
2{-# LANGUAGE DataKinds #-}
2{-# LANGUAGE DataKinds #-}
3{-# LANGUAGE DerivingVia #-}
3{-# LANGUAGE DerivingVia #-}
4−{-# LANGUAGE DerivingVia #-}
6−{-# LANGUAGE StandaloneDeriving #-}
7−{-# LANGUAGE StandaloneDeriving #-}
9−{-# LANGUAGE FlexibleInstances #-}
10{-# LANGUAGE FlexibleInstances #-}
4{-# LANGUAGE FlexibleInstances #-}
12{-# LANGUAGE GADTs #-}
5{-# LANGUAGE GADTs #-}
13−{-# LANGUAGE GADTs #-}
15−{-# LANGUAGE DefaultSignatures #-}
16−{-# LANGUAGE DerivingStrategies #-}
17−{-# LANGUAGE FlexibleInstances #-}
18−{-# LANGUAGE GADTs #-}
19−{-# LANGUAGE GeneralizedNewtypeDeriving #-}
20{-# LANGUAGE LambdaCase #-}
6{-# LANGUAGE LambdaCase #-}
21{-# LANGUAGE MultiParamTypeClasses #-}
7{-# LANGUAGE MultiParamTypeClasses #-}
22{-# LANGUAGE PolyKinds #-}
8{-# LANGUAGE PolyKinds #-}
23{-# LANGUAGE ScopedTypeVariables #-}
9{-# LANGUAGE ScopedTypeVariables #-}
24−{-# LANGUAGE TypeApplications #-}
10+{-# LANGUAGE StandaloneDeriving #-}
25{-# LANGUAGE TypeFamilies #-}
11{-# LANGUAGE TypeFamilies #-}
12+{-# LANGUAGE TypeOperators #-}
26{-# LANGUAGE UndecidableInstances #-}
13{-# LANGUAGE UndecidableInstances #-}
27−{-# LANGUAGE StandaloneDeriving #-}
28−{-# LANGUAGE DerivingVia #-}
31module Roboservant.Types.Breakdown where
15module Roboservant.Types.Breakdown where
33−import Data.Dynamic (Dynamic, fromDynamic, toDyn)
17+import Data.Dynamic (Dynamic, toDyn)
34import Data.List.NonEmpty (NonEmpty (..))
18import Data.List.NonEmpty (NonEmpty (..))
35−import qualified Data.List.NonEmpty as NEL
36−import Data.Maybe (fromMaybe)
37−import GHC.Generics(Generic)
19+import GHC.Generics
38import Data.Typeable (Typeable)
20import Data.Typeable (Typeable)
39import Roboservant.Types.Internal
21import Roboservant.Types.Internal
40import Data.Hashable
22import Data.Hashable
24+import qualified Data.List.NonEmpty as NEL
42−-- | only use this when we are using the internal typerep map.
26+breakdown :: (Hashable x, Typeable x, Breakdown x)
43−promisedDyn :: Typeable a => Dynamic -> a
27+ => x -> NonEmpty (Dynamic, Int)
44−promisedDyn = fromMaybe (error "internal error, typerep map misconstructed") . fromDynamic
28+breakdown x = hashedDyn x :| breakdownExtras x
46class Breakdown x where
30class Breakdown x where
47− breakdown :: x -> NonEmpty (Dynamic,Int)
31+ breakdownExtras :: x -> [(Dynamic,Int)]
48−-- default breakdown :: Typeable x => x -> NonEmpty Dynamic
49−-- breakdown = pure . toDyn
52instance (Hashable x, Typeable x) => Breakdown (Atom x) where
33instance (Hashable x, Typeable x) => Breakdown (Atom x) where
53− breakdown (Atom x) = pure (toDyn x, hash x)
34+ breakdownExtras (Atom x) = [(toDyn x, hash x)]
55deriving via (Atom ()) instance Breakdown ()
36deriving via (Atom ()) instance Breakdown ()
56deriving via (Atom Int) instance Breakdown Int
37deriving via (Atom Int) instance Breakdown Int
38+deriving via (Atom [Char]) instance Breakdown [Char]
40+class GBreakdown (f :: k -> *) where
41+ gBreakdownExtras :: f a -> [(Dynamic,Int)]
43+instance (Hashable x, Typeable x, Generic x, GBreakdown (Rep x)) => Breakdown (Compound (x::Type)) where
44+ breakdownExtras = gBreakdownExtras . from . unCompound
46+instance GBreakdown f => GBreakdown (M1 S c f ) where
47+ gBreakdownExtras (M1 f) = gBreakdownExtras f
49+instance GBreakdown b => GBreakdown (M1 D a b) where
50+ gBreakdownExtras (M1 f) = gBreakdownExtras f
53+instance GBreakdown b => GBreakdown (M1 C a b) where
54+ gBreakdownExtras (M1 f) = gBreakdownExtras f
56+instance (GBreakdown a, GBreakdown b) => GBreakdown (a :*: b) where
57+ gBreakdownExtras (a :*: b) = gBreakdownExtras a <> gBreakdownExtras b
59+instance (GBreakdown a, GBreakdown b) => GBreakdown (a :+: b) where
60+ gBreakdownExtras = \case
61+ L1 a -> gBreakdownExtras a
62+ R1 a -> gBreakdownExtras a
58−-- instance (Typeable a, Breakdown a) => Breakdown [a] where
64+instance (Hashable a, Typeable a, Breakdown a) => GBreakdown (K1 R a) where
59−-- breakdown x = toDyn x :| mconcat (map (NEL.toList . breakdown) x)
65+ gBreakdownExtras (K1 c) = NEL.toList $ breakdown c