Я пытаюсь применить ограничение уровня типа, чтобы список типов типов был такой же длины, что и нагрузка типа Nat. Например, при использовании Длины от Singletons [1] пакета:Ограничения равенства для списков уровней типов
data (n ~ Length ls) => NumList (n :: Nat) (ls :: [*])
test :: Proxy (NumList 2 '[Bool, String, Int])
test = Proxy
Я бы не ожидал этот код для компиляции, поскольку существует несоответствие.
EDIT: Как упоминалось в 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)))
~~~~
EDIT: Сорт ответил на свой вопрос, просто добавьте ограничением для экземпляра:
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