Ich möchte eine Datenstruktur erstellen, um Elemente zu speichern, die auf Typebene mit Symbol gekennzeichnet sind. Dies:Idiomatische Boolesche Gleichheitsverwendung (Singletons)
data Store e (ss :: [Symbol]) where
Nil :: Store e '[]
Cons :: e s -> Store e ss -> Store e (s ': ss)
data HasElem (a :: k) (as :: [k]) where
AtHead :: HasElem a (a ': as)
InTail :: HasElem a as -> HasElem a (b ': as)
class HasElemC (a :: k) (as :: [k]) where hasElem :: HasElem a as
instance HasElemC {OVERLAPPING} a (a ': as) where hasElem = AtHead
instance HasElemC a as => HasElemC a (b ': as) where hasElem = InTail hasElem
from :: HasElemC s ss => Store e ss -> e s
from = from' hasElem
from' :: HasElem s ss -> Store e ss -> e s
-- from' _ Nil = undefined
from' h (Cons element store) = case h of
AtHead -> element
InTail h' -> from' h' store
irgendwie funktioniert, wenn man die Tatsache vernachlässigen, dass Compiler warnt mich nicht liefern from' _ Nil
Definition (? Warum tut es, nebenbei bemerkt ist es eine Möglichkeit, es stoppen zu machen?) Aber was ich wirklich wollte Am Anfang war es, Singletons-Bibliothek in idiomatischer Weise zu verwenden, anstatt meinen eigenen Code auf Typenebene zu schreiben. So etwas wie das:
import Data.Singletons.Prelude.List
data Store e (ss :: [Symbol]) where
Nil :: Store e '[]
Cons :: Sing s -> e s -> Store e ss -> Store e (s ': ss)
from :: Elem s ss ~ True => Store e ss -> e s
from (Cons evidence element nested) = ???
Leider konnte ich nicht herausfinden, wie man den Kontext in eine propositionale Gleichheit umwandeln kann. Wie können Sie Bausteine aus der Singletons-Bibliothek verwenden, um das zu tun, was ich versuche?
[email protected], [email protected]
Sie können die Warnung in 'from' entfernen, indem Sie die Funktionen' storeHead :: Store e (s ': ss) -> es' und 'storeTail :: Store e (s': ss) -> Store e ss hinzufügen 'und benutze sie im Store, nachdem du' AtHead' oder 'InTail' gefunden hast. – cchalmers
Ihre beiden 'HasElemC'-Instanzen überschneiden sich.GHC wird es unmöglich finden, eine 'HasElemC'-Bedingung zu entladen, da die Vorbedingungen bei der Proof-Suche nicht überprüft werden. Glücklicherweise gibt es [einen bekannten Trick mit Typfamilien und "UndecidableInstances"] (https://wiki.haskell.org/GHC/AdvancedOverlap). (In der Tat ist dies eine der wenigen guten Anwendungen von Booleschen Familien.) –
Danke cchalmers, das hat funktioniert. Danke, Benjamin. Überlappungen sind in meinem Fall in Ordnung: Ich brauche keine Funktionen, die in ss polymorph sind. Obwohl ich sie in der Zukunft brauchen könnte. – NioBium