So fand ich endlich eine Aufgabe, wo ich die neue Erweiterung DataKinds
(mit ghc 7.4.1) verwenden könnte. Hier ist die Vec
Ich verwende:Binding Name in Typ Unterschrift mit DataKind
data Nat = Z | S Nat deriving (Eq, Show)
data Vec :: Nat -> * -> * where
Nil :: Vec Z a
Cons :: a -> Vec n a -> Vec (S n) a
nun der Einfachheit halber wollte ich fromList
implementieren. Grundsätzlich kein Problem mit einfacher Rekursion/Faltung - aber ich kann mir nicht vorstellen, wie man den richtigen Typ gibt. Als Referenz ist dies die Agda Version:
fromList : ∀ {a} {A : Set a} → (xs : List A) → Vec A (List.length xs)
Mein Haskell Ansatz, mit der Syntax I here sah:
fromList :: (ls :: [a]) -> Vec (length ls) a
fromList [] = Nil
fromList (x:xs) = Cons x (fromList xs)
Das gibt mir ein parse error on input 'a'
. Ist die Syntax, die ich gefunden habe, sogar korrekt, oder haben sie sie geändert? Ich fügte auch einige Erweiterungen hinzu, die im Code in der Verbindung sind, die auch nicht half (zZ habe ich GADTs, DataKinds, KindSignatures, TypeOperators, TypeFamilies, UndecidableInstances
).
Mein anderer Verdacht war, dass ich einfach nicht polymorphe Typen binden, aber mein Test dafür:
bla :: (n :: Nat) -> a -> Vec (S n) a
bla = undefined
scheiterte auch mit Kind mis-match Expected kind 'ArgKind', but 'n' has kind 'Nat'
(nicht wirklich wissen, was das bedeutet).
Könnte mir jemand mit einer funktionierenden Version von fromList
helfen und auch die anderen Probleme klären? Leider ist DataKinds
noch nicht sehr gut dokumentiert und scheint davon auszugehen, dass jeder, der es benutzt, profunde Kenntnisse der Typentheorie besitzt.
Wow, vielen Dank. Das bringt mich dazu, "DataKinds" wirklich zu verstehen - sie führen mich ein wenig in die Irre. In der Tat dachte ich am Anfang, dass ich die existenziell quantifizierte Version brauchen würde, aber der abhängige Typ sah viel mehr wie das aus, was ich eigentlich vom Typ ausdrücken wollte. Woher kommt aber die Bindesyntax mit '(a :: X) -> Y'? Das habe ich jetzt an einigen Stellen gesehen. – phg
Zum Beispiel wird es verwendet [http://haskell.1045720.n5.nabble.com/Data-Kinds-and-superfluous-in-my-opinion-constraints-contexts-td5689436.html], und ich denke auch [hier] (http://www.typesandotherdistractions.com/2012/02/fun-mit-xpolykinds-polykinded-fold.html). – phg
Ich denke, das meiste von dem, was Sie haben, ist Code auf der Termebene '\ (a :: X) -> y' und/oder Sachen, die' PolyKinds' betreffen. Zum Beispiel: "Datenbox a = Box" und "bla :: Box (n :: Nat) -> a -> Vec n a" –