1 {-# LANGUAGE DeriveFoldable #-}
2 {-# LANGUAGE DeriveGeneric #-}
3 {-# LANGUAGE DeriveTraversable #-}
4 {-# LANGUAGE FlexibleContexts #-}
6 -----------------------------------------------------------------------------
9 -- Module : Distribution.Simple.Flag
10 -- Copyright : Isaac Jones 2003-2004
14 -- Maintainer : cabal-devel@haskell.org
15 -- Portability : portable
17 -- Defines the 'Flag' type and it's 'Monoid' instance, see
18 -- <http://www.haskell.org/pipermail/cabal-devel/2007-December/001509.html>
19 -- for an explanation.
21 -- Split off from "Distribution.Simple.Setup" to break import cycles.
22 module Distribution
.Simple
.Flag
36 import Distribution
.Compat
.Prelude
hiding (get
)
37 import Distribution
.Compat
.Stack
40 -- ------------------------------------------------------------
44 -- ------------------------------------------------------------
46 -- | All flags are monoids, they come in two flavours:
50 -- > --ghc-option=foo --ghc-option=bar
52 -- gives us all the values ["foo", "bar"]
54 -- 2. singular value flags, eg:
56 -- > --enable-foo --disable-foo
58 -- gives us Just False
60 -- So, this 'Flag' type is for the latter singular kind of flag.
61 -- Its monoid instance gives us the behaviour where it starts out as
62 -- 'NoFlag' and later flags override earlier ones.
64 -- Isomorphic to 'Maybe' a.
65 data Flag a
= Flag a | NoFlag
deriving (Eq
, Generic
, Show, Read, Typeable
, Foldable
, Traversable
)
67 instance Binary a
=> Binary
(Flag a
)
68 instance Structured a
=> Structured
(Flag a
)
70 instance Functor Flag
where
71 fmap f
(Flag x
) = Flag
(f x
)
72 fmap _ NoFlag
= NoFlag
74 instance Applicative Flag
where
75 (Flag x
) <*> y
= x
<$> y
79 instance Monoid
(Flag a
) where
83 instance Semigroup
(Flag a
) where
87 instance Bounded a
=> Bounded
(Flag a
) where
88 minBound = toFlag
minBound
89 maxBound = toFlag
maxBound
91 instance Enum a
=> Enum
(Flag a
) where
92 fromEnum = fromEnum . fromFlag
93 toEnum = toFlag
. toEnum
94 enumFrom (Flag a
) = map toFlag
. enumFrom $ a
96 enumFromThen (Flag a
) (Flag b
) = toFlag `
map`
enumFromThen a b
98 enumFromTo (Flag a
) (Flag b
) = toFlag `
map`
enumFromTo a b
100 enumFromThenTo (Flag a
) (Flag b
) (Flag c
) = toFlag `
map`
enumFromThenTo a b c
101 enumFromThenTo _ _ _
= []
103 -- | Wraps a value in 'Flag'.
104 toFlag
:: a
-> Flag a
107 -- | Extracts a value from a 'Flag', and throws an exception on 'NoFlag'.
108 fromFlag
:: WithCallStack
(Flag a
-> a
)
109 fromFlag
(Flag x
) = x
110 fromFlag NoFlag
= error "fromFlag NoFlag. Use fromFlagOrDefault"
112 -- | Extracts a value from a 'Flag', and returns the default value on 'NoFlag'.
113 fromFlagOrDefault
:: a
-> Flag a
-> a
114 fromFlagOrDefault _
(Flag x
) = x
115 fromFlagOrDefault def NoFlag
= def
117 -- | Converts a 'Flag' value to a 'Maybe' value.
118 flagToMaybe
:: Flag a
-> Maybe a
119 flagToMaybe
(Flag x
) = Just x
120 flagToMaybe NoFlag
= Nothing
122 -- | Pushes a function through a 'Flag' value, and returns a default
123 -- if the 'Flag' value is 'NoFlag'.
126 flagElim
:: b
-> (a
-> b
) -> Flag a
-> b
127 flagElim n _ NoFlag
= n
128 flagElim _ f
(Flag x
) = f x
130 -- | Converts a 'Flag' value to a list.
131 flagToList
:: Flag a
-> [a
]
132 flagToList
(Flag x
) = [x
]
133 flagToList NoFlag
= []
135 -- | Returns 'True' only if every 'Flag' 'Bool' value is Flag True, else 'False'.
136 allFlags
:: [Flag
Bool] -> Flag
Bool
138 if all (\f -> fromFlagOrDefault
False f
) flags
142 -- | Converts a 'Maybe' value to a 'Flag' value.
143 maybeToFlag
:: Maybe a
-> Flag a
144 maybeToFlag Nothing
= NoFlag
145 maybeToFlag
(Just x
) = Flag x
147 -- | Merge the elements of a list 'Flag' with another list 'Flag'.
148 mergeListFlag
:: Flag
[a
] -> Flag
[a
] -> Flag
[a
]
149 mergeListFlag currentFlags v
=
150 Flag
$ concat (flagToList currentFlags
++ flagToList v
)
152 -- | Types that represent boolean flags.
153 class BooleanFlag a
where
156 instance BooleanFlag
Bool where