没有强大的背景知识,单例库似乎很难处理。有什么方法可以将像'[1, 2, 3]
这样的级别类型列表转换成像'(1, '(2, '(3, '())))
这样的成对链?
我试图写几行,但是它们为我产生了无表情的错误。
{-# LANGUAGE TypeFamilies, TypeInType #-}
module ExpandList where
import Data.Singletons.Prelude.List
import Data.Singletons.Prelude.Tuple
type family IntoChainOfPairs (xs :: [k]) :: (k, b) where
IntoChainOfPairs (x ': '[]) = '(x, '())
IntoChainOfPairs (x ': xs) = '(x, IntoChainOfPairs xs)
sIntoChainOfPairs :: forall a (t :: [a]). Sing t -> Sing (IntoChainOfPairs t)
sIntoChainOfPairs = \case
SCons a SNil -> STuple2 a STuple0
SCons a b -> STuple2 a (sIntoChainOfPairs b)
所以我陷入了根本的误解。编译器不了解我,我不了解。我确定我的代码在根本上是错误的。
答案 0 :(得分:2)
IntoChainOfPairs
的结果类型应随输入而变化。因此,实际上有两个函数,一个type ToPairsType (xs :: [a]) :: Type
(根据输入计算输出类型)和一个type ToPairs (xs :: [a]) :: ToPairsType xs
(实际计算输出)。
type family ToPairsType (xs :: [a]) :: Type where
ToPairsType '[] = ()
ToPairsType ((_ :: a) : xs) = (a, ToPairsType xs)
type family ToPairs (xs :: [a]) :: ToPairsType xs where
ToPairs '[] = '()
ToPairs (x : xs) = '(x, ToPairs xs)
您定义了一个局部函数,其中b
是IntoChainOfPairs
的参数。你真的写了
type family IntoChainOfPairs (k :: Type) (b :: Type) (xs :: [k]) :: (k, b) where
IntoChainOfPairs k () (x : '[]) = '(x, '())
IntoChainOfPairs k (k, b') (x : xs) = '(x, IntoChainOfPairs k b' xs)
您在b
上进行了部分模式匹配,而在k
上进行了非线性匹配。此外,不自然的(部分!)列表处理也无济于事。您可以使用case
基础结构在Type
上痛苦地获得Typeable
的价值级别sIntoChainOfPairs
,以编写IntoChainOfPairs
,但我不建议这样做。真的,sToPairs
刚刚坏了。
ToPairs
被写为sToPairs :: forall (a :: Type) (xs :: [a]). Sing xs -> Sing (ToPairs xs)
sToPairs SNil = STuple0
sToPairs (SCons x xs) = STuple2 x (sToPairs xs)
的直接“反射”:
func application(_ application: UIApplication, willFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey : Any]? = nil) -> Bool {
do {
try AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayback, mode: AVAudioSessionModeDefault, options: [.mixWithOthers, .allowAirPlay])
print("Playback OK")
try AVAudioSession.sharedInstance().setActive(true)
print("Session is Active")
} catch {
print(error)
}
return true
}