Funktionale Programmierung ist das Programmierparadigma, in dem Sie ohne Verwendung programmieren Variablen. Funktionen rufen andere Funktionen mit auf Variable vorbei zwischen.
Dieses Paradigma ermöglicht Konstanten und Castings mit starkem Typ. Es wird auch mit gekennzeichnet faul bewertung: Ausdrücke werden nicht ausgewertet, bis ein Ergebnis erforderlich ist.
Haskell ist eine funktionale Programmiersprache, die es seit 1987 gibt. Sie verfügt über eine große Gemeinschaft von Programmierern und ist auf Mac-, Windows- und Linux-Plattformen verfügbar.
In diesem Tutorial werde ich ein erstellen Alfred Bibliothek, um Abläufe in Haskell. Dann erstelle ich einen Workflow mit dieser Bibliothek.
In diesem Lernprogramm gehe ich davon aus, dass Sie bereits mit dem Schreiben von Workflows in Alfred vertraut sind. Wenn nicht, schauen Sie sich diese Tutorials an:
Da eine vollständige Beschreibung von Haskell Programmierung ist außerhalb des Rahmens dieses Tutorials. Sie können eine Gentile Einführung in Haskell: Version 98 lesen. Ich habe es selbst gelernt Haskell aus dem freien Buch Schreiben Sie sich ein Schema in 48 Stunden. Ich lerne gern neue Sprachen, indem ich ein Programm schreibe, das nützlich ist.
Benutzen Haskell auf dem Mac brauchst du zuerst XCode Eingerichtet. Dies ist eine kostenlose Installation von der Mac App Store. Nach dem Download starten XCode und öffnen Sie die Voreinstellungsfenster.
In dem Voreinstellungsfenster, klicke auf das Standorte Artikel. Stellen Sie sicher, dass unten Befehlszeilen-Tools zeigt auf Ihre Version von XCode. Es wird nach einem Benutzer-Login gefragt. Nach der Eingabe werden die Befehlszeilentools eingerichtet.
Mit XCode installiert und eingerichtet, laden Sie das herunter Haskell Compiler- und Support-Dateien von Haskell für Mac OS X.
Verschieben Sie nach dem Entpacken der Datei die ghc-7.10.1.app zum Ordner "Applications" (7.10.1 war die neueste Version, als ich dieses Tutorial schrieb).
Das Installationsprogramm zeigt den Code an, der Ihrem hinzugefügt werden soll ~ / .bash_profile Datei und Ihre ~ / .zshrc Datei (wenn Sie Z-Shell verwenden). Wenn Sie diesen Code zu Ihren Shell-Dateien hinzugefügt haben, klicken Sie auf Checkliste aktualisieren. Alle Kontrollkästchen sollten grün sein. Sie können jetzt erstellen Haskell Programme.
Haskell hat einen Paketmanager ähnlich NodeJS's npm. Es ist Kabale. Mit Kabale Sie können viele Bibliotheken von Drittanbietern herunterladen und installieren, in die andere Benutzer geschrieben haben Haskel. Für die Alfred-Haskell-Bibliothek, Sie müssen das installieren TagSoup Bibliothek. Dies hilft beim Abrufen des Bundleids der Alfred Arbeitsablauf. Geben Sie in der Befehlszeile Folgendes ein:
cabal install tagsoup installieren
Erstellen Sie nun eine neue Datei mit dem Namen Alfred.hs
. Alles Haskell Programmdateien enden mit .hs
Erweiterung. Fügen Sie in dieser Datei diesen Code ein:
Modul Alfred (begin, end, addItem, addItemBasic, getAlfredDataFileContents, putAlfredDataFileContents, getAlfredCacheFileContents, putAlfredCacheFileContents) Importieren von System.Process importieren Sie System.Directory System.Environment importieren Sie Text.HTML.TagSoup
Das Modul Alfred (
Startet ein Modul. Alles Haskell Dateien sind Module. In der Klammer werden die Funktionen definiert, die dieses Modul zur Verfügung stellt. Alles Haskell Funktionen beginnen mit einem Kleinbuchstaben. Wenn das Modul das Hauptprogramm sein soll, muss es ein Main
Funktion. Da es sich um eine Bibliothek handelt, enthält sie lediglich Funktionen und Konstanten-Deklarationen.
Nach der Erklärung der Modul
und was es exportiert, schreiben Sie die Liste der verschiedenen verwendeten Bibliotheken. Diese Bibliothek verwendet drei Bibliotheken: System.Prozess
, System.Directory
, System.Umgebung
, und das Text.HTML.TagSoup
dass wir mit heruntergeladen haben Kabale
.
cacheDirBasic :: String cacheDirBasic = "/Library/Caches/com.runningwithcrayons.Alfred-2/Workflow Data /" dataDirBasic :: String dataDirBasic = "/ Library / Anwendungsunterstützung / Alfred 2 / Workflow Data /" begin :: String begin = ""end :: String end =" "
Als nächstes definiere ich drei Konstanten. Die erste Zeile ist die Typdeklaration mit der eigentlichen Definition darunter. Das ::
Das Symbol erklärt, dass die nächsten Elemente Typdeklarationen sind. Hier definieren wir die Konstanten als String
Art.
addItem :: String -> String -> String -> String -> String -> String -> String -> String addItem a b c d e f g = "- "
"++ e ++" "++ f ++" "++ g ++"
Das Artikel hinzufügen
Funktion dauert sieben String
Eingaben und erstellt das XML-Element String
als Ausgabe. Beachten Sie, dass die Typdeklaration wie acht aussieht String
Typen getrennt durch ->
. Das ->
Symbol zeigt den nächsten Typ. Die ersten sieben Typen sind die Eingabe, der letzte ist der Rückgabewert. Alle Funktionen in Haskell müssen einen Rückgabewert haben.
addItemBasic :: String -> String -> String -> String -> String addItemBasic a b c d = addItem a b "ja" "" "c d" icon.png "
Das addItemBasic
verwendet die Artikel hinzufügen
Funktion zum Erstellen eines XML-Elements, wobei drei der Eingänge auf einen Standardwert gesetzt sind.
getBundleID :: IO (String) getBundleID = do-Tags <- fmap parseTags $ readFile "info.plist" let id = fromTagText $ dropWhile (~/= "") (Partitionen (~ ==) ") tags !! 0) !! 1 return id
Das getBundleID
Holen Sie sich die ID des Alfred Workflow-Pakets vom info.plist Datei im Workflow-Verzeichnis. Diese Datei ist ein Klartext plist
. Da dies eine Art XML- oder HTML-Format ist, TextSoup Bibliothek funktioniert sehr gut, um es einzulesen und zu decodieren. Dies ist eine Monadenfunktion (einfach ausgedrückt: eine Funktion, die mit dem Element außerhalb des Programms interagiert. Zum Beispiel: Dateien, GUI usw.). Sie können mehr über Monaden in der Monaden-Tutorial. Jede Funktion mit dem Rückgabetyp von IO ()
ist eine Monade für Eingabe- oder Ausgabefunktionen.
Der funktionale Programmierstil setzt sich hier aus einer Liste von Elementen zusammen. Das tun
Das Keyword sagt: "Führen Sie die folgenden Schritte in Reihenfolge aus"..
Die erste Zeile nach dem tun
liest in der info.plist Datei und analysierte die Tags mit parseTags
von dem TextSoup Bibliothek. Die zweite Zeile findet die erste Dikt
tag und löscht alles bis zum Schnur
Etikett. Es extrahiert dann den Inhalt der Tags und platziert ihn in der Transistionalitätskonstante Ich würde
. Ich würde
ist eine Konstante, weil ihr Wert sich nicht ändern kann. Seit allen Alfred info.plist Dateien haben genau das gleiche Layout, ich muss den Schlüssel nicht testen, um korrekt zu sein. Das Ich würde
Wert wird dann zurückgegeben.
getAlfredDataFileContents :: String -> IO (String) getAlfredDataFileContents fileName = do h <- getHomeDirectory id <- getBundleID let fPath = h ++ dataDirBasic ++ id ++ "/" ++ fileName fExist <- doesFileExist fPath if fExist then do contents <- readFile fPath return contents else return ""
Die nächste Monad-Funktion ruft den Inhalt einer Datei ab, die sich in der Datei befindet Alfred Datenverzeichnis für den Workflow und gibt ihn an die aufrufende Funktion zurück. Die Funktion ruft zuerst das Heimatverzeichnis des Benutzers ab, erhält die Bündel-ID und erstellt einen Pfad zum Alfred Datenverzeichnis für den Workflow und gibt den Inhalt dieser Datei zurück, falls vorhanden. Andernfalls gibt die Funktion eine leere Zeichenfolge zurück.
putAlfredDataFileContents :: String -> String -> IO () putAlfredDataFileContents Dateiname dataStr = do h <- getHomeDirectory id <- getBundleID writeFile (h ++ dataDirBasic ++ id ++ "/" ++ fileName) dataStr
Die nächste Monade macht genau das Gegenteil. Es benötigt einen Dateinamen und die Daten, die in dieser Datei gespeichert werden sollen. Da der Inhalt der Datei mit dem Namen, ob er existiert oder nicht, eingefügt wird, muss das Vorhandensein der Datei nicht festgestellt werden.
getAlfredCacheFileContents :: String -> IO (String) getAlfredCacheFileContents fileName = do h <- getHomeDirectory id <- getBundleID let fPath = h ++ cacheDirBasic ++ id ++ "/" ++ fileName fExist <- doesFileExist fPath if fExist then do contents <- readFile fPath return contents else return "" putAlfredCacheFileContents :: String -> String -> IO () putAlfredCacheFileContents Dateiname dataStr = do h <- getHomeDirectory id <- getBundleID writeFile (h ++ cacheDirBasic ++ id ++ "/" ++ fileName) dataStr
Die letzten beiden Monadenfunktionen in der Bibliothek lesen und schreiben Dateien in der Alfred Cache Verzeichnis für den Workflow.
Mit der erstellten Bibliothek soll ein Workflow geschrieben werden. Erstellen Sie einen neuen Workflow in Alfred namens Haskell-Textkonverter wie gezeigt:
Das Skriptfilter sollte so aussehen:
Klicken Sie jetzt auf Workflow-Ordner öffnen. Dadurch wird der Ordner für den Arbeitsablauf im Finder geöffnet. Legen Sie eine Kopie der Alfred.hs drin. Erstellen Sie nun die Datei cases.hs und platziere diesen Code dort:
Modul Hauptverzeichnis importieren System.Environment importieren System.Exit importieren Data.List importieren Data.Char importiert qualifiziert Data.ByteString importieren qualifiziert Alfred als AL - - Alle Wörter, die nur Großbuchstaben sein sollen. - upperWordsList = [I, II, III, IV, V, VI, VII, VIII, IX, X, HTML, " CSS "," AT & T "," PHP "," UI "] - - Alle Wörter, die nur aus Kleinbuchstaben bestehen sollen. - lowerWordsList = ["to", "an", "und", "at", "as", "aber", "by", "for", "if", "in", "on", " oder "," ist "," mit "," ein "," das "," von "," vs "," vs. "," über "," über "," en "] toWordLower :: String -> String toWordLower a = map toLower a toWordUpper :: String -> String toWordUpper a = mapUser a toFirstLetterUpper :: [Char] -> [Char] toFirstLetterUpper [] = [] toFirstLetterUpper (a: []) = toUpper a: [] toFirstLetterUpper (a: ax) = toUpper a: toWordNiedrigere Axt toFirstLetterUpperOnly :: [Char] -> [Char] toFirstLetterUpperOnly [] = [] toFirstLetterUpperOnly (a: []) = toUpper a: []: a)) a: ax toFirstLetterNowerOnly :: [Char] -> [Char] toFirstLetterLowerOnly [] = [] toFirstLetterLowerOnly (a: []) = toLower a: [] toFirstLetterOnly (a: ax) = toLower a: ax toTitleCase :: [Char] -> [Char] toTitleCase [] = [] toTitleCase a | elem (toWordUpper a) upperWordsList = toWordUpper a | elem (toWordLower a) lowerWordsList = toWordLower a | ansonsten = toFirstLetterUpper a processLine :: String -> (String -> String) -> [String] -> String processLine "" f [a] = concatMap f $ Wörter a processLine cf [a] = init $ concatMap (++ c ) $ map f $ Wörter a procLower :: [String] -> String procLower [a] = toWordLower procUpper :: [String] -> String procUpper [a] = toWordUpper a procSentence :: [String] -> String procSentence [ a] = toFirstLetterUpper a procTitle :: [String] -> String procTitle a = toFirstLetterUpperOnly $ processLine "" toTitleCase a procCamel :: [String] -> String procCamel a = toFirstLetterLowerOnly $ processLine "toFirstLetterUpper a procSlash" > String procSlash a = processLine "/" toWordLower a procPascal :: [String] -> String procPascal a = processLine "" toFirstLetterUpper a procCobra :: [String] -> String procCobra a = processLine "_" toFirstLetterUpper a procDot :: [ String] -> String procDot a = processLine "." toWordLower a procDash :: [String] -> String procDash a = processLine "-" toWordLower a addItemCase :: String -> String -> String -> String -> String addItemCase abc = AL.addItemBasic abbc alfredScript :: [String] -> IO ( ) alfredScript [] = putStr "" alfredScript [caseStr] = do putStr AL.begin putStr (addItemCase "HTCTitle" (procTitle [caseStr]) "title case") putStr (addItemCase "HTCLower" (procLower [caseStr]) "unterer Fall ") putStr (addItemCase" HTCUpper "(procUpper [caseStr])" Großbuchstaben ") putStr (addItemCase" HTCSentenccaseStr "(procSentence [caseStr])" Satz "" putStr (addItemCase "HTCCamel" (procCamel [caseStr]) "Camel Case ") putStr (addItemCase" HTCSlash "(procSlash [caseStr])" Slash Case ") putStr (addItemCase" HTCPascal "(procPascal [caseStr])" Pascal Case ") putStr (addItemCase" HTCCobra "(procCobra [caseStr])" Cobra Case ") putStr (addItemCase" HTCDot "(procDot [caseStr])" Dot Case ") putStr (addItemCase" HTCDash "(procDash [caseStr])" Dash Case ") putStr AL .end main = do args <- getArgs alfredScript args
Dieser Code nimmt eine Zeichenfolge von der Befehlszeile und generiert die Alfred Script Filter XML-Format mit neun verschiedenen Falltypen.
Das Titelkoffer format verwendet zwei Wortlisten, um alle Groß- oder Kleinbuchstaben zu erstellen. Die eigentliche Funktion toTitleCase
verwendet Bedingungszeichen, um zu sehen, ob sich das Wort in der Großbuchstabenliste oder in der Kleinbuchstabenliste befindet. Wenn ja, mach es so. Ansonsten machen Sie einfach den ersten Buchstaben in Großbuchstaben.
Die Helferfunktion processLine
nimmt einen String und eine Funktion, wendet die Funktion auf alle Einträge in einer Liste von Strings an, fügt den String jedem Eintrag hinzu und verkettet die resultierenden Strings miteinander. Diese Funktion verarbeitet viele Fallkonvertierungen für eine vollständige Zeichenfolge.
Ich habe eine Hilfsfunktion erstellt addItemCase
das dupliziert die arg
Wert für die Titel
Wert in der addItemBasic
Funktion in der Alfred Bibliothek. Bei der funktionalen Programmierung geht es darum, Funktionen zu erstellen, die die Arbeit ohne Variationen erledigen!
Die meisten anderen Funktionen sind relativ leicht zu erkennen. Ich gebe dir den Auftrag, dies zu studieren, damit du es dir selbst machen kannst Haskell Arbeitsablauf.
Um das Programm zu kompilieren, geben Sie dies in der Befehlszeile im Verzeichnis des Arbeitsablaufs ein:
ghc cases.hs
Nachdem das Programm kompiliert und der Workflow erstellt wurde, können Sie es jetzt zum Konvertieren von Zeichenfolgen verwenden. In dem Alfred Prompt, Art ht: conv das ist ein Test
.
Das obige Bild zeigt das Ergebnis. Wählen Sie das gewünschte Element aus und es wird in die Zwischenablage eingefügt. Die Downloaddatei enthält eine Kopie dieses Workflows. Ich habe auch eine erweiterte Version unter Haskell Text Converter auf Packal.org.
Außerdem verbessere und verbessere ich ständig das Alfred Bibliothek in Haskell. Sie können immer die aktuellste Version erhalten Alfred-Bibliothek im GitHub-Repository von Haskell.
In diesem Tutorial habe ich Ihnen gezeigt, wie Sie installieren Haskell Erstellen Sie auf Ihrem Mac eine Alfred Bibliothek, um neue Workflows zu erstellen, und erstellt einen Muster-Workflow mit der Bibliothek. Nun ist es an Ihnen, großartig zu werden Alfred Arbeitsabläufe. Bitte teilen Sie sie in den Kommentaren unten.