clash-prelude-1.8.2: src/Clash/Sized/Vector/ToTuple.hs
{-|
Copyright : (C) 2024, Google LLC
License : BSD2 (see the file LICENSE)
Maintainer : QBayLogic B.V. <devops@qbaylogic.com>
Tooling to safely work around @incomplete-uni-patterns@ and @incomplete-patterns@
warnings. See 'vecToTuple' for more information and examples.
Note: This module has been added to make upgrading to GHC 9.2 easier. As of GHC
9.2, the @incomplete-uni-patterns@ has been added to the @-Wall@, making
previously warning-free code now produce warnings.
-}
{-# LANGUAGE CPP #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE TypeFamilyDependencies #-}
-- Purpose of this module
{-# OPTIONS_GHC -Wno-incomplete-patterns #-}
-- For debugging:
-- {-# OPTIONS_GHC -ddump-splices #-}
module Clash.Sized.Vector.ToTuple (VecToTuple(..)) where
import Clash.CPP
import Clash.Sized.Vector
import Clash.Sized.Vector.ToTuple.TH (vecToTupleInstances)
import Data.Tagged (Tagged(..))
#if MIN_VERSION_base(4,18,0)
import Data.Tuple (Solo(MkSolo))
#elif MIN_VERSION_base(4,16,0)
import Data.Tuple (Solo(Solo))
#endif
{- $setup
>>> :set -XMonoLocalBinds -XGADTs
>>> import Clash.Sized.Vector
-}
class VecToTuple a where
type TupType a = r | r -> a
-- | Given a vector with three elements:
--
-- >>> myVec = (1 :> 2 :> 3 :> Nil) :: Vec 3 Int
--
-- The following would produce a warning even though we can be sure
-- no other pattern can ever apply:
--
-- >>> (a :> b :> c :> Nil) = myVec
--
-- 'vecToTuple' can be used to work around the warning:
--
-- >>> (a, b, c) = vecToTuple myVec
--
-- Of course, you will still get an error if you try to match a vector of the
-- wrong length:
--
-- >>> (a, b, c, d) = vecToTuple myVec
-- ...
#if __GLASGOW_HASKELL__ > 900
-- • Couldn't match type: (a, b, c, d)
-- with: (Int, Int, Int)
#else
-- • Couldn't match type: (Int, Int, Int)
-- ^
-- with: (a, b, c, d)
#endif
-- ...
vecToTuple :: a -> TupType a
instance VecToTuple (Vec 0 a) where
type TupType (Vec 0 a) = Tagged a ()
vecToTuple _ = Tagged ()
#if MIN_VERSION_base(4,18,0)
-- | Instead of using 'vecToTuple' for @Vec 1 _@, you could also consider using 'head'
instance VecToTuple (Vec 1 a) where
type TupType (Vec 1 a) = Solo a
vecToTuple (a1 :> _) = MkSolo a1
#elif MIN_VERSION_base(4,16,0)
-- | Instead of using 'vecToTuple' for @Vec 1 _@, you could also consider using 'head'
instance VecToTuple (Vec 1 a) where
type TupType (Vec 1 a) = Solo a
vecToTuple (a1 :> _) = Solo a1
#endif
-- | __NB__: The documentation only shows instances up to /3/-tuples. By
-- default, instances up to and including /12/-tuples will exist. If the flag
-- @large-tuples@ is set instances up to the GHC imposed limit will exist. The
-- GHC imposed limit is either 62 or 64 depending on the GHC version.
instance VecToTuple (Vec 2 a) where
type TupType (Vec 2 a) = (a, a)
vecToTuple (a1 :> a2 :> _) = (a1, a2)
vecToTupleInstances maxTupleSize