FunctorDescription.hs 2.48 KB
Newer Older
1
{-# LANGUAGE FlexibleContexts #-}
2
{-# LANGUAGE AllowAmbiguousTypes #-}
3
{-# LANGUAGE ConstraintKinds #-}
4

5
module Copar.FunctorDescription
6
7
  ( DynFunctorDescription(..)
  , FunctorParser(..)
8
  , FunctorDescription(..)
9
10
  , Suitable
  , ToDynFunctorDescription(..)
11
12
  , formatFunctorDescription
  , formatFunctorDescriptions
13
  , dynPrecedence
14
  , dynFunctorDescription
15
16
  )
where
17

18
19
20
import           Control.DeepSeq (NFData(..))

import           Data.Functor.Classes
21
import           Data.Text                      ( Text )
22
import           Data.Text.Prettyprint          ( Doc
23
                                                , (<+>)
24
                                                , AnsiStyle
25
                                                )
26
import qualified Data.Text.Prettyprint         as Doc
27

28
29
import           Data.Proxy

30
31
32
import           Type.Reflection

import           Copar.FunctorExpression.Printable
33
import           Copar.FunctorExpression.Parser
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
import           Copar.RefinementInterface
import           Copar.Coalgebra.Parser.Class
import           Copar.PrettyShow

type Suitable f
   = ( RefinementInterface f
     , ParseMorphism f
     , Printable f
     , Eq1 f
     , Functor f
     , FunctorDescription f
     , Foldable f
     , Typeable f
     , Traversable f
     , Show1 f
     , NFData (F1 f)
     , NFData (Label f)
     , PrettyShow (Label f)
     , PrettyShow (F1 f))
53

54
class FunctorDescription f where
55
56
57
58
59
60
  name :: Text
  syntaxExample :: Text
  description :: Maybe (Doc AnsiStyle)
  precedence :: Int
  functorExprParser :: FunctorParser f

61
dynFunctorDescription :: forall f. Suitable f => DynFunctorDescription
62
dynFunctorDescription = DynFunctorDescription (Proxy :: Proxy f)
63

64
65
66
67

class ToDynFunctorDescription f where
  toDynFunctorDescription :: f a -> DynFunctorDescription

68
data DynFunctorDescription where
69
  DynFunctorDescription :: Suitable f => Proxy f -> DynFunctorDescription
70
71
72
73
74
75
76
77
78

dynPrecedence :: DynFunctorDescription -> Int
dynPrecedence (DynFunctorDescription (Proxy :: Proxy f)) = precedence @f

formatFunctorDescription :: FunctorDescription f => Proxy f -> Doc AnsiStyle
formatFunctorDescription (Proxy :: Proxy f)= Doc.vsep
  [ Doc.annotate (Doc.bold <> Doc.underlined) (Doc.pretty (name @f))
    <+> Doc.parens (Doc.pretty (syntaxExample @f))
  , maybe mempty ((Doc.line <>) . Doc.indent 4) (description @f)
79
80
81
  , ""
  ]

82
83
formatFunctorDescriptions :: [DynFunctorDescription] -> Doc AnsiStyle
formatFunctorDescriptions = Doc.vsep . map (\(DynFunctorDescription proxy) -> formatFunctorDescription proxy)