Ich schreibe eine Funktion, die einige Suchvorgänge in einer Abfolge beliebiger Symbole durchführt. Ich möchte es generisch genug machen, so dass es auf Listen, Foldable
s sowie auf ByteString
s und Text
s funktioniert. Verallgemeinern es zu Foldable
ist einfach. Aber wie kann man ByteString
s und Text
s einschließen? Sicher könnte ich ByteString
in eine Liste umwandeln und dann meine Funktion anrufen, aber ich würde alle Vorteile verlieren ByteString
s.Eine einzelne Funktion an Listen, ByteStrings und Texten (und vielleicht anderen ähnlichen Darstellungen) arbeiten lassen
ein konkretes Beispiel haben, lassen Sie uns sagen, dass wir eine Histogramm-Funktion machen wollen:
import Control.Monad.State
import qualified Data.Foldable as F
import Data.Map.Strict (Map)
import qualified Data.Map.Strict as Map
import Data.Word
import qualified Data.ByteString as B
import qualified Data.Text as T
type Histogram a = Map a Int
empty :: (Ord a) => Histogram a
empty = Map.empty
histogramStep :: (Ord a) => a -> Histogram a -> Histogram a
histogramStep k = Map.insertWith (+) k 1
histogram :: (Ord a, F.Foldable t) => t a -> Histogram a
histogram = F.foldl (flip histogramStep) empty
Da aber weder ByteString
noch Text Foldable
(es speichert nur Word8
s/Char
s, nicht beliebige Elemente) können, ich bin mit dem Erstellen von mehr Funktionen stecken, die vor genau wie die aussehen, nur mit einer anderen Art Unterschriften:
histogramBS :: B.ByteString -> Histogram Word8
histogramBS = B.foldl (flip histogramStep) empty
histogramText :: T.Text -> Histogram Char
histogramText = T.foldl (flip histogramStep) empty
diese ist etwas, was man in einer funktionalen Sprache wie Haskell nicht erwartet.
Wie man es generisch macht, histogram
ein für allemal zu schreiben?
Sie stellen immer interessante Fragen, weil Sie tief über das nachdenken, was Sie tun, und immer mehr verstehen möchten. +1 – AndrewC