2 Stimmen

haskell-klasse eigenschaftsprüfung

Ich möchte eine Funktion haben, die eine Eigenschaft einer Klasseninstanz überprüft:

class ListWithAtLeastOneElement a where
   list :: [a]
   check :: Bool
   check = (length list) >= 1

aber ich bekomme diesen Fehler beim Kompilieren in GHC: "Die Klassenmethode 'check' erwähnt keine der Typvariablen der Klasse ListWithAtLeastOneElement a Bei der Überprüfung der Klassenmethode: check :: Bool In der Klassendeklaration für 'ListWithAtLeastOneElement'"

Gibt es einen besseren Weg zu tun, was ich will, oder einen Weg, um dies in GHC zu kompilieren?

3voto

jmg Punkte 7015

Sie scheinen zu denken, dass eine Klasse in Haskell wie eine Klasse in einer OO-Sprache ist. Das ist aber nicht der Fall. Sie sollten einen Datentyp oder newtype oder ein Typsynonym verwenden.

newtype NonemptyList a = List1 [a]

fromList :: [a] -> Maybe (NonemptyList a)
fromList []       = Nothing
fromList xs@(_:_) = Just $ List1 xs

check :: NonemptyList a -> Bool
check (List1 xs) = length xs >= 1

2voto

Thomas M. DuBuisson Punkte 63725

Wie jmg sagte, ist das kein gültiges Haskell, also ist es gut, dass GHC es nicht kompiliert! Wenn Sie mit Java vertraut sind, sollten Sie sich Haskells Typklassen wie Java-Interfaces vorstellen. Wenn das nicht hilft, dann sollten Sie vielleicht lesen LYAHs Kapitel über Klassen .

Für Ihr Problem scheint es, dass Sie einen listenähnlichen Datentyp wünschen, der niemals null sein kann. Sie müssen nicht Test für eine solche Eigenschaft, können Sie sie statisch sicherstellen, indem Sie einen Datentyp Typs, der niemals leer sein kann:

-- Notice this data type can never have zero 'a' values!
data NonEmptyList a = NEL a (NonEmptyList a) | Singleton a

-- We can define basic operators for this, just like list has
-- You can't pattern match with them, but there are work-arounds for that if you want to ask
(.:) = NEL  -- concatenate non-empty lists

nelHead :: NonEmptyList a -> a 
nelHead (NEL a _) = a
nelHead (Singleton a) = a

nelTail :: NonEmptyList a -> Maybe (NonEmptyList a)
nelTail (NEL _ b) = Just b
nelTail _ = Nothing

nelTake :: Int -> NonEmptyList a -> NonEmptyList a
nelTake 1 (NEL a _) = Singleton a
nelTake 1 (Singleton a) = Singleton a
nelTake n (NEL a rest) = a .: nelTake (n-1) rest

nelDrop :: Int -> NonEmptyList a -> NonEmptyList a
nelDrop _ (Singleton _) = error "Perhaps I should have used the 'maybe' type"
nelDrop 1 (NEL a r) = r
nelDrop n (NEL a r) = nelDrop (n-1) r

Und so weiter und so fort. Es ist erwähnenswert nelTake y nelDrop sind teilweise, aber nelHead ist total, lustig, da dies das Gegenteil von normalen Listen ist.

1voto

stephen tetley Punkte 4445

Sie müssten die Prüfung zu einer Funktion machen

check :: [a] -> Bool

Das heißt, Sie sind mit einem Datentyp für nicht leere Listen besser dran als mit einer Klasse, denn Klassen in Haskell erfüllen nicht den gleichen Zweck wie Klassen in objektorientierten Sprachen.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X