All dies ist ein bisschen so weit fortgeschritten, wenn Sie nur mit Haskell Sie beginnen nicht das Gefühl, wie Sie dies sofort verstehen haben.
Das heißt, werde ich ein einfaches Beispiel zu Ørjan Antwort hinzufügen, stellen wir eine Klasse wie folgt definiert:
-- | Class for types that can be constructed from a list of items.
class Unfoldable t where
fromList :: [a] -> t a
Jetzt können wir Instanzen für verschiedene Arten definieren:
import Data.Set (Set)
import qualified Data.Set as Set
instance Unfoldable [] where
fromList = id
instance Unfoldable Set where
fromList = Set.fromList
Aber dies hat zwei Schwächen:
- Es ist nicht mit monomorphic funktioniert Typen: Typen, die keinen Parameter für ihren Elementtyp haben. Zum Beispiel sind
ByteString
und Text
monomorph - ihr Elementtyp ist fest auf Char8
bzw. Char
codiert.
- Es wäre schön zu haben
fromList :: Ord k = [(k, v)] -> Map k v, but that definition doesn't support it, because
(k, v) is not a type parameter of
Map`.
mit So TypeFamilies
es möglich ist, um es zu verbessern:
{-# LANGUAGE TypeFamilies, ConstraintKinds #-}
import Data.Monoid
import Data.Set (Set)
import qualified Data.Set as Set
import Data.Map (Map)
import qualified Data.Map as Map
import Data.Text (Text, pack)
import GHC.Exts (Constraint)
class Monoid m => Unfoldable m where
type Element m :: *
type Constraint m :: GHC.Exts.Constraint
type Constraint m =()
fromList :: [Element m] -> m
instance Unfoldable [a] where
type Element [a] = a
fromList as = as
instance Ord a => Unfoldable (Set a) where
type Element (Set a) = a
type Constraint (Set a) = Ord a
fromList = Set.fromList
instance Ord k => Unfoldable (Map k v) where
type Element (Map k v) = (k, v)
type Constraint (Map k v) = Ord k
fromList = Map.fromList
instance Unfoldable Text where
type Element Text = Char
fromList = pack
Blick auf die Art der fromList :: Monoid m => [Element m] -> m
. Grundsätzlich Element m
ist ein Synonym deren Erweiterung ist für jede differenct Wahl von m
:
Element [a] := a
Element (Map k v) := (k ,v)
Element Text := Char
Der andere Trick ist die Verwendung von ConstraintKinds
zu jedem erlauben Klasseninstanz, die individualisierte Einschränkungen für die Typvariablen erfordert (z. B. Ord k
für Map
). Das ist ein Thema für einen anderen Tag ...
Ich sehe jetzt und Danke!Ich denke, es ist vielleicht besser, den GHC-Benutzerhandbuch zu lesen, bevor Sie mit dem Lesen von Quellcode beginnen ... – hl1020