我試圖強制一個類型級別的約束,即類型級別列表必須與類型級別納稅人攜帶的長度相同。例如,使用從單例[1]包長度:類型級別列表上的平等約束
data (n ~ Length ls) => NumList (n :: Nat) (ls :: [*])
test :: Proxy (NumList 2 '[Bool, String, Int])
test = Proxy
我不希望這個代碼被編譯,因爲存在不匹配。
編輯:由於dfeuer提到數據類型上下文不是一個好主意。我能做到在價值層面的比較,但我希望能夠在類型級別要做到這一點:
class NumListLen a
sameLen :: Proxy a -> Bool
instance (KnownNat n, KnownNat (Length m)) => NumListLen (NumList n m) where
sameLen = const $ (natVal (Proxy :: Proxy n)) == (natVal (Proxy :: Proxy (Length m)))
~~~~
編輯:八九不離十回答我自己的問題,只需添加約束到該實例:
class NumListLen a
sameLen :: Proxy a -> Bool
instance (KnownNat n, KnownNat (Length m), n ~ Length m) => NumListLen (NumList n m) where
sameLen = const $ (natVal (Proxy :: Proxy n)) == (natVal (Proxy :: Proxy (Length m)))
/home/aistis/Projects/SingTest/SingTest/app/Main.hs:333:13:
Couldn't match type ‘3’ with ‘2’
In the second argument of ‘($)’, namely ‘sameLen test’
In a stmt of a 'do' block: print $ sameLen test
In the expression:
do { print $ sameLen test;
putStrLn "done!" }
這是一個數據類型上下文。數據類型上下文完全沒用。我懷疑你現在還不能完全按照Haskell的原則來做,但是單身人士可以做一些奇怪的事情...... – dfeuer
是的,你說得對,數據類型的背景並不完全如何會想要這樣做。但他們明白這一點。我能夠確定類型值並在值級別進行比較,但這不是我想要做的。 – sheganinans
你能否更好地解釋一下你的最終目標是什麼?你真的想表達什麼? – dfeuer