1{-# LANGUAGE CPP #-}
2
3#if __GLASGOW_HASKELL__ >= 708
4#define USE_COERCE
5{-# LANGUAGE Trustworthy #-}
6{-# LANGUAGE RankNTypes #-}
7{-# LANGUAGE ScopedTypeVariables #-}
8#else
9{-# LANGUAGE Unsafe #-}
10#endif
11-----------------------------------------------------------------------------
12-- |
13-- Copyright   :  (C) 2016 Edward Kmett and Eric Mertens
14-- License     :  BSD-style (see the file LICENSE)
15-- Maintainer  :  Edward Kmett <ekmett@gmail.com>
16-- Stability   :  experimental
17-- Portability :  non-portable
18--
19-- This module provides a shim around 'coerce' that defaults to 'unsafeCoerce'
20-- on GHC < 7.8. It also exposes a type-restricted version of '(#.)' that
21-- works around a bizarre GHC 7.10–specific bug.
22-----------------------------------------------------------------------------
23module Control.Lens.Internal.Coerce
24  ( coerce
25  , coerce'
26  , (#..)
27  ) where
28
29import Data.Profunctor.Unsafe
30
31#ifdef USE_COERCE
32
33import Data.Coerce
34
35coerce' :: forall a b. Coercible a b => b -> a
36coerce' = coerce (id :: a -> a)
37{-# INLINE coerce' #-}
38
39(#..) :: (Profunctor p, Coercible c b) => (b -> c) -> p a b -> p a c
40(#..) = (#.)
41{-# INLINE (#..) #-}
42
43#else
44
45import Unsafe.Coerce
46
47coerce, coerce' :: a -> b
48coerce  = unsafeCoerce
49coerce' = unsafeCoerce
50{-# INLINE coerce #-}
51{-# INLINE coerce' #-}
52
53(#..) :: Profunctor p => (b -> c) -> p a b -> p a c
54(#..) = (#.)
55{-# INLINE (#..) #-}
56#endif
57