Immer wenn ich über eine neue Sprache nachdenke - haskell in diesem Fall - versuche ich einen primitiven grep-Klon zu hacken, um zu sehen, wie gut die Sprachimplementierung und/oder ihre Bibliotheken bei der Textverarbeitung sind, weil das ein wichtiger Anwendungsfall ist mich.Primitiver aber effizienter Grep-Klon in Haskell?
Inspiriert von code on the haskell wiki, kam ich mit dem folgenden naiven Versuch auf:
{-# LANGUAGE FlexibleContexts, ExistentialQuantification #-}
import Text.Regex.PCRE
import System.Environment
io :: ([String] -> [String]) -> IO()
io f = interact (unlines . f . lines)
regexBool :: forall r l .
(RegexMaker Regex CompOption ExecOption r,
RegexLike Regex l) =>
r -> l -> Bool
regexBool r l = l =~ r :: Bool
grep :: forall r l .
(RegexMaker Regex CompOption ExecOption r, RegexLike Regex l) =>
r -> [l] -> [l]
grep r = filter (regexBool r)
main :: IO()
main = do
argv <- getArgs
io $ grep $ argv !! 0
Dies zu tun, was ich will, es zu sein scheint, aber leider ist es wirklich langsam - etwa 10-mal langsamer als ein Python-Skript, das das Gleiche macht. Ich nehme an, es ist nicht die Regex-Bibliothek, die hier die Schuld trägt, weil es in PCRE anruft, die schnell genug sein sollte (die Umstellung auf Text.Regex.Posix
verlangsamt die Dinge ein wenig weiter). Also muss es die String
Implementierung sein, die aus theoretischer Sicht lehrreich ist, aber ineffizient nach dem, was ich gelesen habe.
Gibt es eine Alternative zu String
s in Haskell, die sowohl effizient und bequem sind (dh es gibt wenig oder keine Reibung, wenn sie mit, dass anstelle von String
s schaltend) und die vollständig und korrekt behandelt UTF-8 kodierten Unicode sowie Wie andere Kodierungen ohne zu viel Aufwand wenn möglich? Etwas, das jeder benutzt, wenn er Textverarbeitung in Haskell macht, aber ich weiß es einfach nicht, weil ich ein kompletter Anfänger bin?
Verwenden Sie [Text] (https://hackage.haskell.org/package/text-1.2.2.1/docs/Data-Text.html) – ErikR
Ich wollte nur darauf hinweisen, dass C-ähnliche Geschwindigkeiten möglich ist, aber Es könnte einige Anstrengungen erfordern. Werfen Sie einen Blick auf __cgrep__ - http://awgn.github.io/cgrep/ – ErikR
'String' ist ein low-performance, Lazy-String, der für einfache kurze Strings" fein "ist, aber für ernsthafte Textmanipulation ungeeignet ist. 'Text' ist der Hochleistungstyp für die Unicode-Textbearbeitung. (Es gibt auch 'ByteString', das ist _nicht_ für Text, sondern für Bytefolgen.) – chi