{-| 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