    {-# LANGUAGE CPP #-}
    #if !defined(SAFE) && defined(__GLASGOW_HASKELL__)
    #define UNSAFE
    {-# LANGUAGE Unsafe #-}
    #endif
    {-# OPTIONS_GHC -Wno-redundant-constraints #-} -- they aren't redundant!
    -----------------------------------------------------------------------------
    -- |
    -- Copyright   :  (C) 2008-2015 Edward Kmett
    -- License     :  BSD-style (see the file LICENSE)
    --
    -- Maintainer  :  Edward Kmett <ekmett@gmail.com>
    -- Stability   :  provisional
    -- Portability :  portable
    --
    ----------------------------------------------------------------------------
    module Data.Void.Unsafe
      ( unsafeVacuous
      , unsafeVacuousM
      ) where

    import Data.Void

    #ifdef UNSAFE
    import Unsafe.Coerce
    #endif

    -- | If 'Void' is uninhabited then any 'Functor' that holds only values of the type 'Void'
    -- is holding no values.
    --
    -- This is only safe for valid functors that do not perform GADT-like analysis on the argument.
    unsafeVacuous :: Functor f => f Void -> f a
    #ifdef UNSAFE
    unsafeVacuous :: forall (f :: * -> *) a. Functor f => f Void -> f a
    unsafeVacuous = f Void -> f a
    forall a b. a -> b
    unsafeCoerce
    #else
    unsafeVacuous = fmap absurd
    #endif

    -- | If 'Void' is uninhabited then any 'Monad' that holds values of type 'Void'
    -- is holding no values.
    --
    -- This is only safe for valid monads that do not perform GADT-like analysis on the argument.
    unsafeVacuousM :: Monad m => m Void -> m a
    #ifdef UNSAFE
    unsafeVacuousM :: forall (m :: * -> *) a. Monad m => m Void -> m a
    unsafeVacuousM = m Void -> m a
    forall a b. a -> b
    unsafeCoerce
    #else
    unsafeVacuousM m = m >>= return . absurd
    #endif