module Language.Fortran.Util.SecondParameter(SecondParameter(..)) where
import GHC.Generics
class SecondParameter a e | a -> e where
getSecondParameter :: a -> e
setSecondParameter :: e -> a -> a
default getSecondParameter :: (Generic a, GSecondParameter (Rep a) e) => a -> e
getSecondParameter a = getSecondParameter' . from $ a
default setSecondParameter :: (Generic a, GSecondParameter (Rep a) e) => e -> a -> a
setSecondParameter e a = to . setSecondParameter' e . from $ a
class GSecondParameter f e where
getSecondParameter' :: f a -> e
setSecondParameter' :: e -> f a -> f a
instance GSecondParameter (K1 i a) e where
getSecondParameter' _ = undefined
setSecondParameter' _ = undefined
instance GSecondParameter a e => GSecondParameter (M1 i c a) e where
getSecondParameter' (M1 x) = getSecondParameter' x
setSecondParameter' e (M1 x) = M1 $ setSecondParameter' e x
instance (GSecondParameter a e, GSecondParameter b e) => GSecondParameter (a :+: b) e where
getSecondParameter' (L1 a) = getSecondParameter' a
getSecondParameter' (R1 a) = getSecondParameter' a
setSecondParameter' e (L1 a) = L1 $ setSecondParameter' e a
setSecondParameter' e (R1 a) = R1 $ setSecondParameter' e a
instance (ParameterLeaf a, GSecondParameter a e, GSecondParameter' b e) => GSecondParameter (a :*: b) e where
getSecondParameter' (a :*: b) =
if isLeaf a
then getSecondParameter'' b
else getSecondParameter' a
setSecondParameter' e (a :*: b) =
if isLeaf a
then a :*: setSecondParameter'' e b
else setSecondParameter' e a :*: b
class GSecondParameter' f e where
getSecondParameter'' :: f a -> e
setSecondParameter'' :: e -> f a -> f a
instance GSecondParameter' a e => GSecondParameter' (M1 i c a) e where
getSecondParameter'' (M1 a) = getSecondParameter'' a
setSecondParameter'' e (M1 a) = M1 $ setSecondParameter'' e a
instance GSecondParameter' a e => GSecondParameter' (a :*: b) e where
getSecondParameter'' (a :*: _) = getSecondParameter'' a
setSecondParameter'' e (a :*: b) = setSecondParameter'' e a :*: b
instance GSecondParameter' (K1 i e) e where
getSecondParameter'' (K1 a) = a
setSecondParameter'' e (K1 a) = K1 e
instance GSecondParameter' (K1 i a) e where
getSecondParameter'' _ = undefined
setSecondParameter'' _ _ = undefined
class ParameterLeaf f where
isLeaf :: f a -> Bool
instance ParameterLeaf (M1 i c a) where
isLeaf _ = True
instance ParameterLeaf (a :*: b) where
isLeaf _ = False