Ich habe eine Frage zur Klassendefinition mit polymorphen Datentypen. Nehmen wir an, der definierte Datentyp ist:
data BTree a = BLeaf a | BNode a (BTree a) (BTree a) deriving(Show)
Nehmen wir an, ich möchte den Wert der Wurzel des Baums abrufen, jedoch innerhalb einer Instanz einer Klasse namens Tree:
class Tree a where
getRoot:: a -> (?) --<- Type of Leave value as return type
und eine Instanz:
instance Tree (BTree a) where
getRoot BLeaf a = a
getRoot BNode a _ _ = a
Ich kann den Typ der Funktion nicht herausfinden (siehe Fragezeichen), da es kein a ist und die Klasse den Parameter der Instanz nicht kennt.
Lassen Sie die Typvariable in der class Tree
Deklaration auf einen Typkonstruktor der Art * -> *
verweisen, und dann können Sie in der Typensignatur von auf den Typ der Werte des Baums verweisen getRoot
.
class Tree t where
getRoot :: t a -> a
instance Tree BTree where
getRoot (BLeaf a) = a
getRoot (BNode a _ _) = a
Eine andere, etwas komplexere Lösung, die es ermöglicht, dass die Baumstruktur von Art ist, *
wäre die Verwendung einer Typklasse mit mehreren Parametern zusammen mit funktionalen Abhängigkeiten .
{-# LANGUAGE FunctionalDependencies, FlexibleInstances #-}
class Tree t a | t -> a where
getRoot :: t -> a
instance Tree (BTree a) a where
getRoot (BLeaf a) = a
getRoot (BNode a _ _) = a
Oder Sie könnten eine Typenfamilie verwenden .
{-# LANGUAGE TypeFamilies #-}
class Tree t where
type Value t
getRoot :: t -> Value t
instance Tree (BTree a) where
type Value (BTree a) = a
getRoot (BLeaf a) = a
getRoot (BNode a _ _) = a
Dieser Artikel stammt aus dem Internet. Bitte geben Sie beim Nachdruck die Quelle an.
Bei Verstößen wenden Sie sich bitte [email protected] Löschen.
Lass mich ein paar Worte sagen