File: Type.hs

package info (click to toggle)
haskell-haskell-gi 0.26.12-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 800 kB
  • sloc: haskell: 8,617; ansic: 74; makefile: 4
file content (87 lines) | stat: -rw-r--r-- 2,479 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
-- | An abstraction for representing type constructors. This is a very
-- simplified version of `Data.Typeable`, which we don't use directly
-- to avoid compatibility headaches.
module Data.GI.CodeGen.Type
    ( Type(..)  -- Reexported for convenience.
    , BasicType(..)

    , TypeRep

    , con
    , con0

    , typeShow
    , typeConName

    , io
    , ptr
    , funptr
    , maybeT
    ) where

#if !MIN_VERSION_base(4,11,0)
import Data.Monoid ((<>))
#endif
import qualified Data.Text as T
import Data.Text (Text)

import Data.GI.GIR.BasicTypes (Type(..), BasicType(..))

-- | A fully applied type.
data TypeRep = TypeRep { typeCon     :: TypeCon
                       , typeConArgs :: [TypeRep]
                       } deriving (Eq)

-- | A type constructor. We single out some specific constructors
-- since they have special syntax in their Haskell representation.
data TypeCon = TupleCon
             | ListCon
             | TextualCon Text
  deriving (Eq)

-- | Give a valid Haskell source representation of the given
-- `TypeRep`.
typeShow :: TypeRep -> Text
typeShow (TypeRep TupleCon args) =
  "(" <> T.intercalate ", " (map typeShow args) <> ")"
typeShow (TypeRep ListCon args) =
  "[" <> T.intercalate ", " (map typeShow args) <> "]"
typeShow (TypeRep (TextualCon con) args) =
  T.intercalate " " (con : map (parenthesize . typeShow) args)
  where parenthesize :: Text -> Text
        parenthesize s = if T.any (== ' ') s
                         then "(" <> s <> ")"
                         else s

-- | Return a textual representation of the type constructor for the
-- given `TypeRep`.
typeConName :: TypeRep -> Text
typeConName (TypeRep TupleCon _) = "(,)"
typeConName (TypeRep ListCon _) = "[,]"
typeConName (TypeRep (TextualCon s) _) = s

-- | Type constructor applied to the given types.
con :: Text -> [TypeRep] -> TypeRep
con "[]" xs = TypeRep {typeCon = ListCon, typeConArgs = xs }
con "(,)" xs = TypeRep {typeCon = TupleCon, typeConArgs = xs }
con s xs = TypeRep {typeCon = TextualCon s, typeConArgs = xs}

-- | A shorthand for a type constructor taking no arguments.
con0 :: Text -> TypeRep
con0 c = con c []

-- | Embed in the `IO` monad.
io :: TypeRep -> TypeRep
io t = "IO" `con` [t]

-- | A `Ptr` to the type.
ptr :: TypeRep -> TypeRep
ptr t = "Ptr" `con` [t]

-- | A `FunPtr` to the type.
funptr :: TypeRep -> TypeRep
funptr t = "FunPtr" `con` [t]

-- | Embed in the `Maybe` monad.
maybeT :: TypeRep -> TypeRep
maybeT t = "Maybe" `con` [t]