Ich habe eine Daten Familie endlicher Vektoren:Kann ich die Anwesenheit von Instanzen zur Laufzeit überprüfen?
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
ich auch eine Familie von Getter Funktionen haben:
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
Auf diese Weise Zugriff auf die Elemente eines Vektors wird zum Zeitpunkt der Kompilierung überprüft, so dies kompiliert:
get @0 (Vec2f 0 1)
und dies nicht:
get @4 (Vec2f 0 1)
Nun frage ich mich, ob ich mit diesen Funktionen Laufzeitvergleiche schreiben kann. Ich versuchte dies:
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
Ich glaube, ich habe Anwesenheit von Get i n e
Instanz zur Laufzeit zu überprüfen, ist es eine Möglichkeit, es zu tun?
Was ist 'p' in der letzten Zeile' return (get pv) '? Meintest du "iProx"? –
@AlexeyVagarenko ja, tut mir leid! hat den Namen der Variablen während einer Bearbeitung geändert und vergessen, diese Instanz zu tauschen. –