content: -- The `concat <$> sequence _` is to not run afoul of '-fconstraint-solver-iterations' -- temp?
  
  {-# OPTIONS_HADDOCK show-extensions #-}
  
  -- {-# LANGUAGE ConstraintKinds #-}
  {-# LANGUAGE DataKinds #-}
  {-# LANGUAGE ExistentialQuantification #-}
  {-# LANGUAGE FlexibleContexts #-}
  {-# LANGUAGE FlexibleInstances #-}
  -- {-# LANGUAGE GADTs, NoMonoLocalBinds #-}
  {-# LANGUAGE InstanceSigs #-}
  {-# LANGUAGE KindSignatures #-}
  {-# LANGUAGE MultiParamTypeClasses #-}
  {-# LANGUAGE PolyKinds #-}
  -- {-# LANGUAGE RankNTypes #-}
  {-# LANGUAGE ScopedTypeVariables #-}
  {-# LANGUAGE TypeFamilies, NoMonoLocalBinds #-}
  {-# LANGUAGE TypeOperators #-}
  -- Needed for nested type family application:
  {-# LANGUAGE UndecidableInstances #-}
  
  {-# LANGUAGE NoIncoherentInstances #-}
  {-# LANGUAGE NoMonomorphismRestriction #-}
  
  
  --{-# LANGUAGE RankNTypes #-}
  
  module Vivid.SynthDef.FromUA (
       FromUA(..)
     , fromUAWithDefaults
     , uaArgVal
     , uaArgValWDefault
     , DefaultArgs(..)
     , OverwritingArgs(..)
     , UA(..)
     , NoDefaults(..)
     , none
     , Args
     , SDBody
  
     , AllEqual
     ) where
  
  -- import Vivid.SynthDef
  import Vivid.SynthDef.ToSig
  import Vivid.SynthDef.Types
  -- import Vivid.SynthDef.TypesafeArgs
  
  import qualified Data.List as L
  import qualified Data.Map as Map
  import Data.Monoid
  import Data.Proxy
  import GHC.Exts
  import GHC.TypeLits
  
  type SDBody a = SDBody' (SDBodyArgs a)
  
  class FromUA (a :: *) where
     type UAsArgs a :: [Symbol]
     type SDBodyArgs a :: [Symbol]
     fromUA :: a -> SDBody a [(String, Signal)]
  
  fromUAWithDefaults :: (
       FromUA a, FromUA b
     , SDBodyArgs a ~ SDBodyArgs b
     ) => DefaultArgs a -> OverwritingArgs b -> SDBody a [(String, Signal)]
  fromUAWithDefaults (DefaultArgs defaultArgs) (OverwritingArgs overwritingArgs) = do
     defaultArgs' <- fromUA defaultArgs
     overwritingArgs' <- fromUA overwritingArgs
     return . Map.toList $
        Map.unionWith
           (\_defaultArg overwritingArg -> overwritingArg)
           (Map.fromList defaultArgs')
           (Map.fromList overwritingArgs')
  
  -- Newtypes so we don't accidentally flip argument order:
  newtype DefaultArgs a = DefaultArgs a
  newtype OverwritingArgs a = OverwritingArgs a
  
  data NoDefaults (args :: [Symbol])
     = NoDefaults
   deriving (Show, Eq, Ord, Read)
  
  none :: NoDefaults args
  none = NoDefaults
  
  uaArgVal :: (FromUA as, Elem aToLookUp (UAsArgs as), KnownSymbol aToLookUp) => as -> proxy aToLookUp -> SDBody as Signal
  uaArgVal uaArgs proxy = do
     allSigs <- fromUA uaArgs
     return $ case L.lookup (symbolVal proxy) (allSigs::[(String,Signal)]) of
        Just x -> x
        Nothing -> error $ "whaaaaaaaat?: " ++ symbolVal proxy
  
  -- Note a typo in this one won't be caught -- it'll just use the default value
  uaArgValWDefault :: (FromUA as, KnownSymbol aToLookUp, ToSig defaultVal (SDBodyArgs as)) => defaultVal -> as -> proxy aToLookUp -> SDBody as Signal
  uaArgValWDefault defaultVal uaArgs proxy = do
     allSigs <- fromUA uaArgs
     case L.lookup (symbolVal proxy) (allSigs::[(String,Signal)]) of
        Just x -> return x
        Nothing -> toSig defaultVal
  
  -- instance (args0 ~ args1) => FromUA (NoDefaults args0) args1 where
  instance FromUA (NoDefaults args0) where
     type UAsArgs (NoDefaults args0) = '[]
     type SDBodyArgs (NoDefaults args0) = args0
     fromUA _ = return []
  
  instance FromUA (UA a args) where
     type UAsArgs (UA a args) = '[a]
     type SDBodyArgs (UA a args) = args
     fromUA :: UA a args -> SDBody (UA a args) [(String, Signal)]
     fromUA (UA x) = do
        y <- x
        return [(symbolVal (Proxy::Proxy a), y)]
        -- The LHS is like "freq" and the RHS is the value -- lhs isn't the 'foo' in 'A::A "foo"' ^^
  
  instance (args0 ~ args1, KnownSymbol a {-, KnownSymbol b -}) => FromUA (UA a args0, UA b args1) where
     type UAsArgs (UA a args0, UA b args1) = '[a, b]
     type SDBodyArgs (UA a args0, UA b args1) = args0
     fromUA (a, b) = (<>) <$> fromUA a <*> fromUA b
  
  instance (AllEqual '[as0,as1,as2], KnownSymbol a, KnownSymbol b)
           => FromUA (UA a as0, UA b as1, UA c as2) where
     type UAsArgs (UA a as0, UA b as1, UA c as2) = '[a, b, c]
     type SDBodyArgs (UA a as0, UA b as1, UA c as2) = as0
     fromUA (a, b, c) =
        -- (<>) <$> fromUA a <*> fromUA (b, c)
        concat <$> sequence [fromUA a, fromUA b, fromUA c]
  
  
  instance (AllEqual '[as0,as1,as2,as3,as4], AllKnownSymbols '[a, b, c])
           => FromUA (UA a as0, UA b as1, UA c as2, UA d as3) where
     type UAsArgs (UA a as0, UA b as1, UA c as2, UA d as3) = '[a, b, c, d]
     type SDBodyArgs (UA a as0, UA b as1, UA c as2, UA d as3) = as0
     fromUA (a, b, c, d) =
        -- (<>) <$> fromUA (a,b) <*> fromUA (c,d)
        concat <$> sequence [fromUA a,fromUA b,fromUA c, fromUA d]
  
  
  
  instance (AllEqual '[as0,as1,as2,as3,as4], AllKnownSymbols '[a,b,c,d] -- , KnownSymbol e --,
  --     (SDBodyArgs (UA a as0)) ~ (UghRename (UA b as1, UA c as2, UA d as3, UA e as4))
            )
           => FromUA (UA a as0, UA b as1, UA c as2, UA d as3, UA e as4) where
     type UAsArgs (UA a as0, UA b as1, UA c as2, UA d as3, UA e as4) = '[a, b, c, d, e]
     type SDBodyArgs (UA a as0, UA b as1, UA c as2, UA d as3, UA e as4) = as0
     fromUA (a, b, c, d, e) =
        -- (<>) <$> fromUA (a,b,c) <*> fromUA (d,e)
        concat <$> sequence [fromUA a,fromUA b,fromUA c,fromUA d,fromUA e]
  
  -- 6:
  instance (AllEqual '[as0,as1,as2,as3,as4,as5], AllKnownSymbols '[a,b,c,d,e,f])
           => FromUA (UA a as0, UA b as1, UA c as2, UA d as3, UA e as4, UA f as5) where
     type UAsArgs (UA a as0, UA b as1, UA c as2, UA d as3, UA e as4, UA f as5) = '[a, b, c, d, e, f]
     type SDBodyArgs (UA a as0, UA b as1, UA c as2, UA d as3, UA e as4, UA f as5) = as0
     fromUA (a, b, c, d, e, f) =
        -- (<>) <$> fromUA (a,b,c) <*> fromUA (d,e,f)
        concat <$> sequence [fromUA a,fromUA b,fromUA c,fromUA d,fromUA e
           ,fromUA f]
  
  -- 7:
  instance (AllEqual '[as0,as1,as2,as3,as4,as5,as6], AllKnownSymbols '[a,b,c,d,e,f,g])
           => FromUA (UA a as0, UA b as1, UA c as2, UA d as3, UA e as4, UA f as5, UA g as6) where
     type UAsArgs (UA a as0, UA b as1, UA c as2, UA d as3, UA e as4, UA f as5,UA g as6) = '[a, b, c, d, e, f, g]
     type SDBodyArgs (UA a as0, UA b as1, UA c as2, UA d as3, UA e as4, UA f as5,UA g as6) = as0
     fromUA (a,b,c,d,e,f,g) =
        -- concat <$> sequence [fromUA (a,b,c),fromUA (d,e,f), fromUA g]
        -- (<>) <$> fromUA (a,b,c,d) <*> fromUA (e,f,g)
        concat <$> sequence [fromUA a,fromUA b,fromUA c, fromUA d,fromUA e
           ,fromUA f, fromUA g]
  
  -- 8
  instance (AllEqual '[as0,as1,as2,as3,as4,as5,as6,as7]
           , AllKnownSymbols '[a,b,c,d,e,f,g,h])
           => FromUA (UA a as0, UA b as1, UA c as2, UA d as3, UA e as4, UA f as5
                     ,UA g as6,UA h as7) where
     type UAsArgs (UA a as0, UA b as1, UA c as2, UA d as3, UA e as4, UA f as5,UA g as6,UA h as7) = '[a, b, c, d, e, f, g, h]
     type SDBodyArgs (UA a as0, UA b as1, UA c as2, UA d as3, UA e as4, UA f as5,UA g as6,UA h as7) = as0
     fromUA (a,b,c,d,e,f,g,h) =
        -- (<>) <$> fromUA (a,b,c,d) <*> fromUA (e,f,g,h)
        -- concat <$> sequence [fromUA (a,b,c), fromUA (d,e,f), fromUA (g,h)]
        concat <$> sequence [fromUA a,fromUA b,fromUA c, fromUA d,fromUA e
           ,fromUA f, fromUA g, fromUA h]
  
  -- 9:
  instance (AllEqual '[as0,as1,as2,as3,as4,as5,as6,as7,as8]
           ,AllKnownSymbols '[a,b,c,d,e,f,g,h,i])
           => FromUA (UA a as0, UA b as1, UA c as2, UA d as3, UA e as4, UA f as5
                     ,UA g as6,UA h as7,UA i as8) where
     type UAsArgs (UA a as0, UA b as1, UA c as2, UA d as3, UA e as4, UA f as5,UA g as6,UA h as7,UA i as8) = '[a, b, c, d, e, f, g, h, i]
     type SDBodyArgs (UA a as0, UA b as1, UA c as2, UA d as3, UA e as4, UA f as5,UA g as6,UA h as7,UA i as8) = as0
     fromUA (a,b,c,d,e,f,g,h,i) =
        -- (<>) <$> fromUA (a,b,c,d,e) <*> fromUA (f,g,h,i)
        concat <$> sequence [fromUA (a,b,c), fromUA (d,e,f), fromUA (g,h,i)]
  
  
  instance (AllEqual '[as0,as1,as2,as3,as4,as5,as6,as7,as8,as9]
           ,AllKnownSymbols '[a,b,c,d,e,f,g,h,i,j])
           => FromUA (UA a as0, UA b as1, UA c as2, UA d as3, UA e as4, UA f as5
                     ,UA g as6,UA h as7,UA i as8,UA j as9) where
     type UAsArgs (UA a as0, UA b as1, UA c as2, UA d as3, UA e as4, UA f as5
                  ,UA g as6,UA h as7,UA i as8,UA j as9) =
            '[a,b,c,d,e,f,g,h,i,j]
     type SDBodyArgs (UA a as0, UA b as1, UA c as2, UA d as3, UA e as4, UA f as5,UA g as6,UA h as7,UA i as8,UA j as9) = as0
     fromUA (a,b,c,d,e,f,g,h,i,j) =
        -- (<>) <$> fromUA (a,b,c,d,e) <*> fromUA (f,g,h,i,j)
        concat <$> sequence [fromUA (a,b,c), fromUA (d,e,f), fromUA (g,h,i), fromUA (j)]
  
  instance (AllEqual '[as0,as1,as2,as3,as4,as5,as6,as7,as8,as9,as10]
           ,AllKnownSymbols '[a,b,c,d,e,f,g,h,i,j,k])
           => FromUA (UA a as0, UA b as1, UA c as2, UA d as3, UA e as4, UA f as5
                     ,UA g as6,UA h as7,UA i as8,UA j as9,UA k as10) where
     type UAsArgs (UA a as0, UA b as1, UA c as2, UA d as3, UA e as4, UA f as5
                  ,UA g as6,UA h as7,UA i as8,UA j as9,UA k as10) =
            '[a,b,c,d,e,f,g,h,i,j,k]
     type SDBodyArgs (UA a as0, UA b as1, UA c as2, UA d as3, UA e as4, UA f as5,UA g as6,UA h as7,UA i as8,UA j as9,UA k as10) = as0
     fromUA (a,b,c,d,e,f,g,h,i,j,k) =
        -- (<>) <$> fromUA (a,b,c,d,e,f) <*> fromUA (g,h,i,j,k)
        concat <$> sequence [fromUA (a,b,c), fromUA (d,e,f), fromUA (g,h,i), fromUA (j,k)]
  
  
  instance (AllEqual '[as0,as1,as2,as3,as4,as5,as6,as7,as8,as9,as10,as11]
           ,AllKnownSymbols '[a,b,c,d,e,f,g,h,i,j,k,l])
           => FromUA (UA a as0, UA b as1, UA c as2, UA d as3, UA e as4, UA f as5
                     ,UA g as6,UA h as7,UA i as8,UA j as9,UA k as10,UA l as11) where
     type UAsArgs (UA a as0, UA b as1, UA c as2, UA d as3, UA e as4, UA f as5
                  ,UA g as6,UA h as7,UA i as8,UA j as9,UA k as10,UA l as11) =
            '[a,b,c,d,e,f,g,h,i,j,k,l]
     type SDBodyArgs (UA a as0, UA b as1, UA c as2, UA d as3, UA e as4, UA f as5,UA g as6,UA h as7,UA i as8,UA j as9,UA k as10,UA l as11) = as0
     fromUA (a,b,c,d,e,f,g,h,i,j,k,l) =
        -- (<>) <$> fromUA (a,b,c,d,e,f) <*> fromUA (g,h,i,j,k,l)
        concat <$> sequence [fromUA (a,b,c), fromUA (d,e,f), fromUA (g,h,i), fromUA (j,k,l)]
  
  
  instance (AllEqual '[as0,as1,as2,as3,as4,as5,as6,as7,as8,as9,as10,as11,as12]
           ,AllKnownSymbols '[a,b,c,d,e,f,g,h,i,j,k,l,m])
           => FromUA (UA a as0, UA b as1, UA c as2, UA d as3, UA e as4, UA f as5
                     ,UA g as6,UA h as7,UA i as8,UA j as9,UA k as10,UA l as11
                     ,UA m as12
                     ) where
     type UAsArgs (UA a as0, UA b as1, UA c as2, UA d as3, UA e as4, UA f as5
                  ,UA g as6,UA h as7,UA i as8,UA j as9,UA k as10,UA l as11
                  ,UA m as12) =
            '[a,b,c,d,e,f,g,h,i,j,k,l,m]
     type SDBodyArgs (UA a as0, UA b as1, UA c as2, UA d as3, UA e as4, UA f as5,UA g as6,UA h as7,UA i as8,UA j as9,UA k as10,UA l as11,UA m as12) = as0
     fromUA (a,b,c,d,e,f,g,h,i,j,k,l,m) =
        -- (<>) <$> fromUA (a,b,c,d,e,f,g) <*> fromUA (h,i,j,k,l,m)
        concat <$> sequence [fromUA (a,b,c), fromUA (d,e,f), fromUA (g,h,i), fromUA (j,k,l), fromUA (m)]
  
  
  instance (AllEqual '[as0,as1,as2,as3,as4,as5,as6,as7,as8,as9,as10,as11,as12,as13]
           ,AllKnownSymbols '[a,b,c,d,e,f,g,h,i,j,k,l,m,n])
           => FromUA (UA a as0, UA b as1, UA c as2, UA d as3, UA e as4, UA f as5
                     ,UA g as6,UA h as7,UA i as8,UA j as9,UA k as10,UA l as11
                     ,UA m as12,UA n as13
                     ) where
     type UAsArgs (UA a as0, UA b as1, UA c as2, UA d as3, UA e as4, UA f as5
                  ,UA g as6,UA h as7,UA i as8,UA j as9,UA k as10,UA l as11
                  ,UA m as12,UA n as13) =
            '[a,b,c,d,e,f,g,h,i,j,k,l,m,n]
     type SDBodyArgs (UA a as0, UA b as1, UA c as2, UA d as3, UA e as4, UA f as5,UA g as6,UA h as7,UA i as8,UA j as9,UA k as10,UA l as11,UA m as12,UA n as13) = as0
     fromUA (a,b,c,d,e,f,g,h,i,j,k,l,m,n) =
        -- (<>) <$> fromUA (a,b,c,d,e,f,g) <*> fromUA (h,i,j,k,l,m,n)
        concat <$> sequence [fromUA (a,b,c), fromUA (d,e,f), fromUA (g,h,i), fromUA (j,k,l), fromUA (m,n)]
  
  
  instance (AllEqual '[as0,as1,as2,as3,as4,as5,as6,as7,as8,as9,as10,as11,as12,as13,as14]
           ,AllKnownSymbols '[a,b,c,d,e,f,g,h,i,j,k,l,m,n,o])
           => FromUA (UA a as0, UA b as1, UA c as2, UA d as3, UA e as4, UA f as5
                     ,UA g as6,UA h as7,UA i as8,UA j as9,UA k as10,UA l as11
                     ,UA m as12,UA n as13,UA o as14
                     ) where
     type UAsArgs (UA a as0, UA b as1, UA c as2, UA d as3, UA e as4, UA f as5
                  ,UA g as6,UA h as7,UA i as8,UA j as9,UA k as10,UA l as11
                  ,UA m as12,UA n as13,UA o as14
                  ) =
            '[a,b,c,d,e,f,g,h,i,j,k,l,m,n,o]
     type SDBodyArgs (UA a as0, UA b as1, UA c as2, UA d as3, UA e as4, UA f as5
                    ,UA g as6,UA h as7,UA i as8,UA j as9,UA k as10,UA l as11
                    ,UA m as12,UA n as13,UA o as14
                    ) = as0
     fromUA (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o) =
        -- (<>) <$> fromUA (a,b,c,d,e,f,g,h) <*> fromUA (i,j,k,l,m,n,o)
        concat <$> sequence [fromUA (a,b,c), fromUA (d,e,f), fromUA (g,h,i), fromUA (j,k,l), fromUA (m,n,o)]
  
  
  instance (AllEqual '[as0,as1,as2,as3,as4,as5,as6,as7,as8,as9,as10,as11,as12,as13,as14,as15]
           ,AllKnownSymbols '[a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p])
           => FromUA (UA a as0, UA b as1, UA c as2, UA d as3, UA e as4, UA f as5
                     ,UA g as6,UA h as7,UA i as8,UA j as9,UA k as10,UA l as11
                     ,UA m as12,UA n as13,UA o as14,UA p as15
                     ) where
     type UAsArgs (UA a as0, UA b as1, UA c as2, UA d as3, UA e as4, UA f as5
                  ,UA g as6,UA h as7,UA i as8,UA j as9,UA k as10,UA l as11
                  ,UA m as12,UA n as13,UA o as14,UA p as15
                  ) =
            '[a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p]
     type SDBodyArgs (UA a as0, UA b as1, UA c as2, UA d as3, UA e as4, UA f as5
                    ,UA g as6,UA h as7,UA i as8,UA j as9,UA k as10,UA l as11
                    ,UA m as12,UA n as13,UA o as14,UA p as15
                    ) = as0
     fromUA (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p) =
        -- (<>) <$> fromUA (a,b,c,d,e,f,g,h) <*> fromUA (i,j,k,l,m,n,o,p)
        concat <$> sequence [fromUA (a,b,c), fromUA (d,e,f), fromUA (g,h,i), fromUA (j,k,l), fromUA (m,n,o), fromUA (p)]
  
  
  instance (AllEqual '[as0,as1,as2,as3,as4,as5,as6,as7,as8,as9,as10,as11,as12,as13,as14,as15,as16]
           ,AllKnownSymbols '[a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q])
           => FromUA (UA a as0, UA b as1, UA c as2, UA d as3, UA e as4, UA f as5
                     ,UA g as6,UA h as7,UA i as8,UA j as9,UA k as10,UA l as11
                     ,UA m as12,UA n as13,UA o as14,UA p as15,UA q as16
                     ) where
     type UAsArgs (UA a as0, UA b as1, UA c as2, UA d as3, UA e as4, UA f as5
                  ,UA g as6,UA h as7,UA i as8,UA j as9,UA k as10,UA l as11
                  ,UA m as12,UA n as13,UA o as14,UA p as15,UA q as16
                  ) =
            '[a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q]
     type SDBodyArgs (UA a as0, UA b as1, UA c as2, UA d as3, UA e as4, UA f as5
                    ,UA g as6,UA h as7,UA i as8,UA j as9,UA k as10,UA l as11
                    ,UA m as12,UA n as13,UA o as14,UA p as15,UA q as16
                    ) = as0
     fromUA (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q) =
        -- (<>) <$> fromUA (a,b,c,d,e,f,g,h,i) <*> fromUA (j,k,l,m,n,o,p,q)
        concat <$> sequence [fromUA (a,b,c), fromUA (d,e,f), fromUA (g,h,i), fromUA (j,k,l), fromUA (m,n,o), fromUA (p,q)]
  
  
  instance (AllEqual '[as0,as1,as2,as3,as4,as5,as6,as7,as8,as9,as10,as11,as12,as13,as14,as15,as16,as17]
           ,AllKnownSymbols '[a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r])
           => FromUA (UA a as0, UA b as1, UA c as2, UA d as3, UA e as4, UA f as5
                     ,UA g as6,UA h as7,UA i as8,UA j as9,UA k as10,UA l as11
                     ,UA m as12,UA n as13,UA o as14,UA p as15,UA q as16
                     ,UA r as17
                     ) where
     type UAsArgs (UA a as0, UA b as1, UA c as2, UA d as3, UA e as4, UA f as5
                  ,UA g as6,UA h as7,UA i as8,UA j as9,UA k as10,UA l as11
                  ,UA m as12,UA n as13,UA o as14,UA p as15,UA q as16,UA r as17
                  ) =
            '[a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r]
     type SDBodyArgs (UA a as0, UA b as1, UA c as2, UA d as3, UA e as4, UA f as5
                    ,UA g as6,UA h as7,UA i as8,UA j as9,UA k as10,UA l as11
                    ,UA m as12,UA n as13,UA o as14,UA p as15,UA q as16,UA r as17
                    ) = as0
     fromUA (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r) =
        -- (<>) <$> fromUA (a,b,c,d,e,f,g,h,i) <*> fromUA (j,k,l,m,n,o,p,q,r)
        concat <$> sequence [fromUA (a,b,c), fromUA (d,e,f), fromUA (g,h,i), fromUA (j,k,l), fromUA (m,n,o), fromUA (p,q,r)]
  
  
  instance (AllEqual '[as0,as1,as2,as3,as4,as5,as6,as7,as8,as9,as10,as11,as12,as13,as14,as15,as16,as17,as18]
           ,AllKnownSymbols '[a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s])
           => FromUA (UA a as0, UA b as1, UA c as2, UA d as3, UA e as4, UA f as5
                     ,UA g as6,UA h as7,UA i as8,UA j as9,UA k as10,UA l as11
                     ,UA m as12,UA n as13,UA o as14,UA p as15,UA q as16
                     ,UA r as17, UA s as18
                     ) where
     type UAsArgs (UA a as0, UA b as1, UA c as2, UA d as3, UA e as4, UA f as5
                  ,UA g as6,UA h as7,UA i as8,UA j as9,UA k as10,UA l as11
                  ,UA m as12,UA n as13,UA o as14,UA p as15,UA q as16,UA r as17
                  ,UA s as18) =
            '[a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s]
     type SDBodyArgs (UA a as0, UA b as1, UA c as2, UA d as3, UA e as4, UA f as5
                    ,UA g as6,UA h as7,UA i as8,UA j as9,UA k as10,UA l as11
                    ,UA m as12,UA n as13,UA o as14,UA p as15,UA q as16,UA r as17
                    ,UA s as18) = as0
     fromUA (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s) =
        -- (<>) <$> fromUA (a,b,c,d,e,f,g,h,i,j) <*> fromUA (k,l,m,n,o,p,q,r,s)
        concat <$> sequence [fromUA (a,b,c), fromUA (d,e,f), fromUA (g,h,i), fromUA (j,k,l), fromUA (m,n,o), fromUA (p,q,r), fromUA (s)]
  
  instance (AllEqual '[as0,as1,as2,as3,as4,as5,as6,as7,as8,as9,as10,as11,as12,as13,as14,as15,as16,as17,as18,as19]
           ,AllKnownSymbols '[a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t])
           => FromUA (UA a as0, UA b as1, UA c as2, UA d as3, UA e as4, UA f as5
                     ,UA g as6,UA h as7,UA i as8,UA j as9,UA k as10,UA l as11
                     ,UA m as12,UA n as13,UA o as14,UA p as15,UA q as16
                     ,UA r as17, UA s as18,UA t as19
                     ) where
     type UAsArgs (UA a as0, UA b as1, UA c as2, UA d as3, UA e as4, UA f as5
                  ,UA g as6,UA h as7,UA i as8,UA j as9,UA k as10,UA l as11
                  ,UA m as12,UA n as13,UA o as14,UA p as15,UA q as16,UA r as17
                  ,UA s as18,UA t as19) =
            '[a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t]
     type SDBodyArgs (UA a as0, UA b as1, UA c as2, UA d as3, UA e as4, UA f as5
                    ,UA g as6,UA h as7,UA i as8,UA j as9,UA k as10,UA l as11
                    ,UA m as12,UA n as13,UA o as14,UA p as15,UA q as16,UA r as17
                    ,UA s as18,UA t as19) = as0
     fromUA (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t) =
        -- (<>) <$> fromUA (a,b,c,d,e,f,g,h,i,j) <*> fromUA (k,l,m,n,o,p,q,r,s,t)
        concat <$> sequence [fromUA (a,b,c), fromUA (d,e,f), fromUA (g,h,i), fromUA (j,k,l), fromUA (m,n,o), fromUA (p,q,r), fromUA (s,t)]
  
  instance (AllEqual '[as0,as1,as2,as3,as4,as5,as6,as7,as8,as9,as10,as11,as12,as13,as14,as15,as16,as17,as18,as19,as20]
           ,AllKnownSymbols '[a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u])
           => FromUA (UA a as0, UA b as1, UA c as2, UA d as3, UA e as4, UA f as5
                     ,UA g as6,UA h as7,UA i as8,UA j as9,UA k as10,UA l as11
                     ,UA m as12,UA n as13,UA o as14,UA p as15,UA q as16
                     ,UA r as17, UA s as18,UA t as19,UA u as20
                     ) where
     type UAsArgs (UA a as0, UA b as1, UA c as2, UA d as3, UA e as4, UA f as5
                  ,UA g as6,UA h as7,UA i as8,UA j as9,UA k as10,UA l as11
                  ,UA m as12,UA n as13,UA o as14,UA p as15,UA q as16,UA r as17
                  ,UA s as18,UA t as19,UA u as20
                  ) =
            '[a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u]
     type SDBodyArgs (UA a as0, UA b as1, UA c as2, UA d as3, UA e as4, UA f as5
                    ,UA g as6,UA h as7,UA i as8,UA j as9,UA k as10,UA l as11
                    ,UA m as12,UA n as13,UA o as14,UA p as15,UA q as16,UA r as17
                    ,UA s as18,UA t as19,UA u as20
                    ) = as0
     fromUA (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u) =
        -- (<>) <$> fromUA (a,b,c,d,e,f,g,h,i,j,k) <*> fromUA (l,m,n,o,p,q,r,s,t,u)
        concat <$> sequence [fromUA (a,b,c), fromUA (d,e,f), fromUA (g,h,i), fromUA (j,k,l), fromUA (m,n,o), fromUA (p,q,r), fromUA (s,t,u)]
  
  instance (AllEqual '[as0,as1,as2,as3,as4,as5,as6,as7,as8,as9,as10,as11,as12,as13,as14,as15,as16,as17,as18,as19,as20,as21]
           ,AllKnownSymbols '[a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v])
           => FromUA (UA a as0, UA b as1, UA c as2, UA d as3, UA e as4, UA f as5
                     ,UA g as6,UA h as7,UA i as8,UA j as9,UA k as10,UA l as11
                     ,UA m as12,UA n as13,UA o as14,UA p as15,UA q as16
                     ,UA r as17, UA s as18,UA t as19,UA u as20,UA v as21
                     ) where
     type UAsArgs (UA a as0, UA b as1, UA c as2, UA d as3, UA e as4, UA f as5
                  ,UA g as6,UA h as7,UA i as8,UA j as9,UA k as10,UA l as11
                  ,UA m as12,UA n as13,UA o as14,UA p as15,UA q as16,UA r as17
                  ,UA s as18,UA t as19,UA u as20,UA v as21
                  ) =
            '[a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v]
     type SDBodyArgs (UA a as0, UA b as1, UA c as2, UA d as3, UA e as4, UA f as5
                    ,UA g as6,UA h as7,UA i as8,UA j as9,UA k as10,UA l as11
                    ,UA m as12,UA n as13,UA o as14,UA p as15,UA q as16,UA r as17
                    ,UA s as18,UA t as19,UA u as20,UA v as21
                    ) = as0
     fromUA (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v) =
        -- (<>) <$> fromUA (a,b,c,d,e,f,g,h,i,j,k) <*> fromUA (l,m,n,o,p,q,r,s,t,u,v)
        concat <$> sequence [fromUA (a,b,c), fromUA (d,e,f), fromUA (g,h,i), fromUA (j,k,l), fromUA (m,n,o), fromUA (p,q,r), fromUA (s,t,u), fromUA (v)]
  
  instance (AllEqual '[as0,as1,as2,as3,as4,as5,as6,as7,as8,as9,as10,as11,as12,as13,as14,as15,as16,as17,as18,as19,as20,as21,as22]
           ,AllKnownSymbols '[a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w])
           => FromUA (UA a as0, UA b as1, UA c as2, UA d as3, UA e as4, UA f as5
                     ,UA g as6,UA h as7,UA i as8,UA j as9,UA k as10,UA l as11
                     ,UA m as12,UA n as13,UA o as14,UA p as15,UA q as16
                     ,UA r as17, UA s as18,UA t as19,UA u as20,UA v as21
                     ,UA w as22
                     ) where
     type UAsArgs (UA a as0, UA b as1, UA c as2, UA d as3, UA e as4, UA f as5
                  ,UA g as6,UA h as7,UA i as8,UA j as9,UA k as10,UA l as11
                  ,UA m as12,UA n as13,UA o as14,UA p as15,UA q as16,UA r as17
                  ,UA s as18,UA t as19,UA u as20,UA v as21,UA w as22
                  ) =
            '[a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w]
     type SDBodyArgs (UA a as0, UA b as1, UA c as2, UA d as3, UA e as4, UA f as5
                    ,UA g as6,UA h as7,UA i as8,UA j as9,UA k as10,UA l as11
                    ,UA m as12,UA n as13,UA o as14,UA p as15,UA q as16,UA r as17
                    ,UA s as18,UA t as19,UA u as20,UA v as21,UA w as22
                    ) = as0
     fromUA (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w) =
        -- (<>) <$> fromUA (a,b,c,d,e,f,g,h,i,j,k,l) <*> fromUA (m,n,o,p,q,r,s,t,u,v,w)
        concat <$> sequence [fromUA (a,b,c), fromUA (d,e,f), fromUA (g,h,i), fromUA (j,k,l), fromUA (m,n,o), fromUA (p,q,r), fromUA (s,t,u), fromUA (v,w)]
  
  instance (AllEqual '[as0,as1,as2,as3,as4,as5,as6,as7,as8,as9,as10,as11,as12,as13,as14,as15,as16,as17,as18,as19,as20,as21,as22,as23]
           ,AllKnownSymbols '[a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x])
           => FromUA (UA a as0, UA b as1, UA c as2, UA d as3, UA e as4, UA f as5
                     ,UA g as6,UA h as7,UA i as8,UA j as9,UA k as10,UA l as11
                     ,UA m as12,UA n as13,UA o as14,UA p as15,UA q as16
                     ,UA r as17, UA s as18,UA t as19,UA u as20,UA v as21
                     ,UA w as22,UA x as23
                     ) where
     type UAsArgs (UA a as0, UA b as1, UA c as2, UA d as3, UA e as4, UA f as5
                  ,UA g as6,UA h as7,UA i as8,UA j as9,UA k as10,UA l as11
                  ,UA m as12,UA n as13,UA o as14,UA p as15,UA q as16,UA r as17
                  ,UA s as18,UA t as19,UA u as20,UA v as21,UA w as22,UA x as23
                  ) =
            '[a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x]
     type SDBodyArgs (UA a as0, UA b as1, UA c as2, UA d as3, UA e as4, UA f as5
                    ,UA g as6,UA h as7,UA i as8,UA j as9,UA k as10,UA l as11
                    ,UA m as12,UA n as13,UA o as14,UA p as15,UA q as16,UA r as17
                    ,UA s as18,UA t as19,UA u as20,UA v as21,UA w as22,UA x as23
                    ) = as0
     fromUA (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x) =
        -- (<>) <$> fromUA (a,b,c,d,e,f,g,h,i,j,k,l) <*> fromUA (m,n,o,p,q,r,s,t,u,v,w,x)
        concat <$> sequence [fromUA (a,b,c), fromUA (d,e,f), fromUA (g,h,i), fromUA (j,k,l), fromUA (m,n,o), fromUA (p,q,r), fromUA (s,t,u), fromUA (v,w,x)]
  
  instance (AllEqual '[as0,as1,as2,as3,as4,as5,as6,as7,as8,as9,as10,as11,as12,as13,as14,as15,as16,as17,as18,as19,as20,as21,as22,as23,as24]
           ,AllKnownSymbols '[a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y])
           => FromUA (UA a as0, UA b as1, UA c as2, UA d as3, UA e as4, UA f as5
                     ,UA g as6,UA h as7,UA i as8,UA j as9,UA k as10,UA l as11
                     ,UA m as12,UA n as13,UA o as14,UA p as15,UA q as16
                     ,UA r as17, UA s as18,UA t as19,UA u as20,UA v as21
                     ,UA w as22,UA x as23,UA y as24
                     ) where
     type UAsArgs (UA a as0, UA b as1, UA c as2, UA d as3, UA e as4, UA f as5
                  ,UA g as6,UA h as7,UA i as8,UA j as9,UA k as10,UA l as11
                  ,UA m as12,UA n as13,UA o as14,UA p as15,UA q as16,UA r as17
                  ,UA s as18,UA t as19,UA u as20,UA v as21,UA w as22,UA x as23
                  ,UA y as24) =
            '[a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y]
     type SDBodyArgs (UA a as0, UA b as1, UA c as2, UA d as3, UA e as4, UA f as5
                    ,UA g as6,UA h as7,UA i as8,UA j as9,UA k as10,UA l as11
                    ,UA m as12,UA n as13,UA o as14,UA p as15,UA q as16,UA r as17
                    ,UA s as18,UA t as19,UA u as20,UA v as21,UA w as22,UA x as23
                    ,UA y as24) = as0
     fromUA (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y) =
        -- (<>) <$> fromUA (a,b,c,d,e,f,g,h,i,j,k,l,m) <*> fromUA (n,o,p,q,r,s,t,u,v,w,x,y)
        concat <$> sequence [fromUA (a,b,c), fromUA (d,e,f), fromUA (g,h,i), fromUA (j,k,l), fromUA (m,n,o), fromUA (p,q,r), fromUA (s,t,u), fromUA (v,w,x), fromUA (y)]
  
  instance (AllEqual '[as0,as1,as2,as3,as4,as5,as6,as7,as8,as9,as10,as11,as12,as13,as14,as15,as16,as17,as18,as19,as20,as21,as22,as23,as24,as25]
           ,AllKnownSymbols '[a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z])
           => FromUA (UA a as0, UA b as1, UA c as2, UA d as3, UA e as4, UA f as5
                     ,UA g as6,UA h as7,UA i as8,UA j as9,UA k as10,UA l as11
                     ,UA m as12,UA n as13,UA o as14,UA p as15,UA q as16
                     ,UA r as17, UA s as18,UA t as19,UA u as20,UA v as21
                     ,UA w as22,UA x as23,UA y as24,UA z as25
                     ) where
     type UAsArgs (UA a as0, UA b as1, UA c as2, UA d as3, UA e as4, UA f as5
                  ,UA g as6,UA h as7,UA i as8,UA j as9,UA k as10,UA l as11
                  ,UA m as12,UA n as13,UA o as14,UA p as15,UA q as16,UA r as17
                  ,UA s as18,UA t as19,UA u as20,UA v as21,UA w as22,UA x as23
                  ,UA y as24,UA z as25) =
            '[a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z]
     type SDBodyArgs (UA a as0, UA b as1, UA c as2, UA d as3, UA e as4, UA f as5
                    ,UA g as6,UA h as7,UA i as8,UA j as9,UA k as10,UA l as11
                    ,UA m as12,UA n as13,UA o as14,UA p as15,UA q as16,UA r as17
                    ,UA s as18,UA t as19,UA u as20,UA v as21,UA w as22,UA x as23
                    ,UA y as24,UA z as25) = as0
     fromUA (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z) =
        -- (<>) <$> fromUA (a,b,c,d,e,f,g,h,i,j,k,l,m) <*> fromUA (n,o,p,q,r,s,t,u,v,w,x,y,z)
        concat <$> sequence [fromUA (a,b,c), fromUA (d,e,f), fromUA (g,h,i), fromUA (j,k,l), fromUA (m,n,o), fromUA (p,q,r), fromUA (s,t,u), fromUA (v,w,x), fromUA (y,z)]
  
  
  -- | \"UGen Arg\"
  data UA (name :: Symbol) (args :: [Symbol]) =
     KnownSymbol name => UA (SDBody' args Signal)
  
  
  type family AllEqual (a :: [[Symbol]]) :: Constraint where
     AllEqual '[] = ()
     AllEqual (a ': '[b]) = (a ~ b)
     AllEqual (a ': b ': cs) = (a ~ b, (AllEqual (a ': cs)))
  
  type family AllKnownSymbols (a :: [ks]) :: Constraint where
     AllKnownSymbols '[] = ()
     AllKnownSymbols (ks0 ': kss) = (KnownSymbol ks0, AllKnownSymbols kss)
  
  type family EachElems (forEach :: [Symbol]) args :: Constraint where
     EachElems (x ': xs) args = (Elem x args, EachElems xs args)
     EachElems '[] args = ()
  
  type family Args (required :: [Symbol])
                   (optional :: [Symbol])
                   args
              :: Constraint where
     Args required optional args =
        ( Subset required (UAsArgs args)
        , Subset (UAsArgs args) (SetUnion required optional)
        , FromUA args
        -- , EachElems required (UAsArgs args)
        -- , EachElems optional (UAsArgs args)
        )
  
  