|
1 |
| -{-# LANGUAGE CPP #-} |
2 |
| -{-# LANGUAGE Rank2Types #-} |
| 1 | +{-# LANGUAGE CPP #-} |
| 2 | +{-# LANGUAGE DataKinds #-} |
| 3 | +{-# LANGUAGE Rank2Types #-} |
| 4 | +{-# LANGUAGE TypeFamilies #-} |
| 5 | +{-# LANGUAGE TypeOperators #-} |
| 6 | +{-# LANGUAGE UndecidableInstances #-} |
3 | 7 |
|
4 | 8 | {- |
|
5 | 9 | Copyright: (c) 2018-2020 Kowainik
|
@@ -62,10 +66,12 @@ module Colog.Core.Action
|
62 | 66 | import Control.Monad (when, (<=<), (>=>))
|
63 | 67 | import Data.Coerce (coerce)
|
64 | 68 | import Data.Foldable (fold, for_, traverse_)
|
| 69 | +import Data.Kind (Constraint) |
65 | 70 | import Data.List.NonEmpty (NonEmpty (..))
|
66 | 71 | import Data.Monoid (Monoid (..))
|
67 | 72 | import Data.Semigroup (Semigroup (..), stimesMonoid)
|
68 | 73 | import Data.Void (Void, absurd)
|
| 74 | +import GHC.TypeLits (ErrorMessage (..), TypeError) |
69 | 75 |
|
70 | 76 | #if MIN_VERSION_base(4,12,0)
|
71 | 77 | import qualified Data.Functor.Contravariant as Contravariant
|
@@ -144,13 +150,68 @@ instance Applicative m => Monoid (LogAction m a) where
|
144 | 150 |
|
145 | 151 | #if MIN_VERSION_base(4,12,0)
|
146 | 152 | instance Contravariant.Contravariant (LogAction m) where
|
| 153 | + contramap :: (a -> b) -> LogAction m b -> LogAction m a |
147 | 154 | contramap = cmap
|
148 | 155 | {-# INLINE contramap #-}
|
149 | 156 |
|
| 157 | + (>$) :: b -> LogAction m b -> LogAction m a |
150 | 158 | (>$) = (Colog.Core.Action.>$)
|
151 | 159 | {-# INLINE (>$) #-}
|
152 | 160 | #endif
|
153 | 161 |
|
| 162 | +-- | For tracking usage of unrepresentable class instances of 'LogAction'. |
| 163 | +type family UnrepresentableClass :: Constraint |
| 164 | + where |
| 165 | + UnrepresentableClass = TypeError |
| 166 | + ( 'Text "'LogAction' cannot have a 'Functor' instance by design." |
| 167 | + ':$$: 'Text "However, you've attempted to use this instance." |
| 168 | +#if MIN_VERSION_base(4,12,0) |
| 169 | + ':$$: 'Text "" |
| 170 | + ':$$: 'Text "Probably you meant 'Contravariant' class instance with the following methods:" |
| 171 | + ':$$: 'Text " * contramap :: (a -> b) -> LogAction m b -> LogAction m a" |
| 172 | + ':$$: 'Text " * (>$) :: b -> LogAction m b -> LogAction m a" |
| 173 | +#endif |
| 174 | + ) |
| 175 | + |
| 176 | +{- | ⚠️__CAUTION__⚠️ This instance is for custom error display only. |
| 177 | +
|
| 178 | +'LogAction' is not supposed to have 'Functor' instance by design. |
| 179 | +
|
| 180 | +In case it is used by mistake, the user will see the following: |
| 181 | +
|
| 182 | +#if MIN_VERSION_base(4,12,0) |
| 183 | +
|
| 184 | +>>> fmap show logStringStdout |
| 185 | +... |
| 186 | +... 'LogAction' cannot have a 'Functor' instance by design. |
| 187 | + However, you've attempted to use this instance. |
| 188 | +... |
| 189 | + Probably you meant 'Contravariant' class instance with the following methods: |
| 190 | + * contramap :: (a -> b) -> LogAction m b -> LogAction m a |
| 191 | + * (>$) :: b -> LogAction m b -> LogAction m a |
| 192 | +... |
| 193 | +
|
| 194 | +
|
| 195 | +#else |
| 196 | +
|
| 197 | +>>> fmap show logStringStdout |
| 198 | +... |
| 199 | +... 'LogAction' cannot have a 'Functor' instance by design. |
| 200 | + However, you've attempted to use this instance. |
| 201 | +... |
| 202 | +
|
| 203 | +#endif |
| 204 | +
|
| 205 | +@since 0.2.1.0 |
| 206 | +-} |
| 207 | +instance UnrepresentableClass => Functor (LogAction m) where |
| 208 | + fmap :: (a -> b) -> LogAction m a -> LogAction m b |
| 209 | + fmap _ _ = error "Unreachable Functor instance of LogAction" |
| 210 | + |
| 211 | + (<$) :: a -> LogAction m b -> LogAction m a |
| 212 | + _ <$ _ = error "Unreachable Functor instance of LogAction" |
| 213 | + |
| 214 | + |
154 | 215 | {- | Operator version of 'unLogAction'. Note that because of the types, something like:
|
155 | 216 |
|
156 | 217 | @
|
|
0 commit comments