У меня есть семья данных конечных векторов:Могу ли я проверить присутствие экземпляра во время выполнения?
data family Vec (n :: Nat) e
data instance Vec 2 Float = Vec2f !Float !Float
data instance Vec 3 Float = Vec3f !Float !Float !Float
-- and so on
У меня также есть семейство функций геттерных:
class Get (i :: Nat) (n :: Nat) e where
get :: Vec n e -> e
instance Get 0 2 Float where
get (Vec2f x _) = x
instance Get 1 2 Float where
get (Vec2f _ x) = x
instance Get 0 3 Float where
get (Vec3f x _ _) = x
instance Get 1 3 Float where
get (Vec3f _ x _) = x
instance Get 2 3 Float where
get (Vec3f _ _ x) = x
-- and so on
Таким образом, доступ к элементам вектора проверяются во время компиляции, так это составляет:
get @0 (Vec2f 0 1)
и это не делает:
get @4 (Vec2f 0 1)
Теперь я задаюсь вопросом, могу ли я писать проверку диапазона выполнения с помощью этих функций. Я попытался это:
get' :: forall n e. (KnownNat n) => Integer -> Vec n e -> Maybe e
get' i v =
if i >= 0 && i < natVal (Proxy :: Proxy n)
then (flip fmap) (someNatVal i) $ \(SomeNat (Proxy :: Proxy i)) ->
get @i v -- Could not deduce (Get i n e)
else Nothing
Я думаю, что я должен проверить наличие Get i n e
экземпляра во время выполнения, есть способ сделать это?
Что такое 'p' в последней строке' return (get p v) '? Вы имели в виду 'iProx'? –
@ Алексей Вагаренко да, извините! изменил имя переменной во время редактирования и забыл обменивать этот экземпляр. –