Friday 29 September 2017

Haskell Trading System


Välkommen till Hackage. Hackage är Haskells communitys centrala paketarkiv med öppen källkodspaket. Författare använder det för att publicera sina bibliotek och program medan andra Haskell-programmörer använder verktyg som cabal-install för att hämta och installera paket eller folk får paketen via deras distro. Detta webbgränssnitt till Hackage kan du. Browse paket sorterade efter category. Search för paket med nyckelord i namn eller beskrivning. Se vilka paket som har laddats upp nyligen. Uppdatera dina egna paket till Hackage notera att du behöver ett konto. Each paketet innehåller en beskrivning av vad den gör. Licence information. Author information. A downloadable gzipped tarball. En lista över moduler i paketet. Haddock dokumentation om det är tillgängligt med källlänkar. Guidelines for Hackage Packages. All paket ska följa Paketversionspolicy PVP. Packages kan inte raderas, så du bör överväga att ladda upp nya versioner som paketkandidat och testning innan du publicerar den till Huvudindex. Till sidan för huvudpaketlistan finns det några andra paketindex. Administrativa problem. Reportera problem. För problem med konton eller behörigheter, var vänlig kontakta administratörerna via e-post på. För fel med webbplatskoden eller serverhotellproblem , var snäll och rapportera dem i vår problemspårare. Bidra till utvecklingen. Koden är på github och vi välkomnar dragförfrågningar. Det finns öppna biljetter som beskriver befintliga fel och funktioner som vi vill ha eller som behöver förbättras. Hjälp på något av dessa skulle Uppskattas mycket. Det finns en del utvecklare och användardokumentation på githubs wiki, inklusive en snabbguide för att få din egen serverinstans igång. Du kan ställa frågor på cabal-devel-postlistan eller på IRC i hackage-kanalen på freenode. Den nya servern har en automatiskt genererad webbplats api Detta är främst avsedd som dokumentation för personer som arbetar med servern, snarare än som en användarorienterad sidokarta, men det kan vara intressant att se E exakt vad som är tillgängligt Detta inkluderar viktiga resurser som det maskinläsbara indexet för paket som används av kunder som cabal-install. Well-Typed och Industrial Haskell Group IHG är mycket glada att meddela att Hackage 2 nu driver den officiella Hackage-servern. Läs vidare för en översikt över de nya funktionerna, systemförbättringarna och för detaljer om hur du kan bidra till att göra Hackage 2 ännu bättre. Stöd från Industrial Haskell Group. IHG är ett konsortium av företag som är beroende av Haskell. IHG-medlemmarna har finansierade ansträngningarna för att få Hackage 2 att uppnå paritet och göra det klart för övergången. IHG finansierade denna insats för att medan volontärarbetet fick oss de första 90 sätten där, inklusive att lägga till ett antal nya funktioner, var det fortfarande de senaste 90 att göra det för att göra det klart. IHG-medlemmarna bestämde sig för att finansiera Hackage 2 inte bara för att de är bra medborgare, men av upplyst självintresse. Hackage har över 5000 paket skrivna av över 1000 peop le inklusive världens bästa Haskell-utvecklare Detta är en enorm resurs IHG-medlemmarna inser att förbättringar av verktyg och infrastruktur som samhället använder hjälper samhället att producera mer och bättre kod Det här är en fördel för alla i samhället, inklusive kommersiella användare. HiG är angelägen om att öka sitt medlemskap så att fler resurser kan användas för att förbättra Haskells utvecklingsplattform Om din organisation är beroende av Haskell på något sätt kan du överväga att gå med på Se IHGs hemsida för mer information eller kontakta. hjälp från IHG för att komma till denna punkt är Hackage ett samhällsprojekt och dess framgång beror på att gemenskapen behåller och förbättrar den nya servern ytterligare. Koden är nu på github så det är lättare att bidra, och nu när servern är live det finns mer omedelbar tillfredsställelse för frivilliga som bidrar till reparationer och nya funktioner. Det snabbaste innehållsfördelningsnätverket. Som gemenskapens behov ökar Hackage och andra delar av vår infrastruktur kräver ökad mängd bandbredd, lägre latens och mer lagrings - och beräkningsresurser. Hackage innehåller kod skrivet från människor över hela världen, och uppetid och hastighet är avgörande för en ren användarupplevelse när man utvecklar . har erbjudit samhället obegränsat tillträde till deras CDN, vilket gör det möjligt för oss att driva TB-data genom sina kantsystem, tillhandahålla resursskärmning för servrar och få realtidsanalys för alla våra användare och data. Nya funktioner. Även om vår huvudprioritet har varit funktionen paritet så att vi kan byta över, har frivilliga bidragit till flera nya funktioner, bland annat bättre paket sökning, ett nytt webbplats tema, förbättrad säkerhet, möjligheten att fixa paket beroenden efter en release, changelogs och ett REST-stil gränssnitt. Se nya funktioner sidan för mer information om dessa, plus detaljer om andra funktioner som delvis implementeras eller behöver förbättras. så gör vi det här uppdraget på Uni och jag har ett seriöst begär att göra uppdraget i haskell. Det är en simulering av en aktiehandel motor Situationen är att vi har data som kommer in från ett csv och vi vill analysera varje post och bearbeta den på ett visst sätt beroende på vilken marknadsfas det tilldelas Motivering för användning av haske Det är jag som ser tradingmotorn som ett tungt funktionellt system. Jag har haft haskell erfarenhet innan men bara mindre erfarenhet, aldrig någonting så stor. Vi ville vilja köra en tråd som skulle importera csvs till en kö av obehandlade order och sedan har huvudprogrammet åtkomst till den här köen för att behandla varje beställning. Hur kan jag uppnå detta jag vet i C skulle jag bara konfigurera klassen så att den kunde komma åt CSVParser-klassen som skulle hålla den obearbetade köen. Det betyder också att importtråden skulle vara kontinuerligt går igenom alla marknadsfaser eller tills det är färdigt att importera csv-filen. En ny vägledning om hur man åstadkommer detta skulle vara bra att inte leta efter ett helt skrivet manus, precis vad saker i haskell jag skulle behöva titta på. vid 23 33. stängt som inte en riktig fråga av Ritch Melton dflemstr Flexo Michael Petrotta Graviton Mar 30 12 på 1 45. Det är svårt att berätta vad som ställs här här Den här frågan är tvetydig, vag, ofullständig, alltför bred eller retoriskt och kan inte rimligt besvaras i sin nuvarande form För hjälp med att klargöra denna fråga så att den kan öppnas igen, gå till hjälpcentret Om den här frågan kan omformuleras för att passa reglerna i hjälpcentret, var vänlig redigera frågan. Innehållsförteckning. långt har vi pratat mest om högkoncept Haskell kan också användas för programmering på lägre nivå Det är ganska möjligt att skriva program som gränsar till operativsystemet på en låg nivå med hjälp av Haskell. I detta kapitel går vi Att försöka något ambitiöst ett Perl-liknande språk som är giltigt Haskell, implementerat i rent Haskell, vilket gör skalskriptning enkelt. Vi ska implementera rörledningar, lätt kommandokallokation och några enkla verktyg för att hantera uppgifter som annars skulle kunna utföras med grep eller sed. Specialiserade moduler finns för olika operativsystem I detta kapitel kommer vi att använda generiska OS-oberoende moduler så mycket som möjligt. Vi kommer dock att fokusera på POSIX-miljöen fo R mycket av kapitlet POSIX är en standard för Unix-liknande operativsystem som Linux, FreeBSD, MacOS X eller Solaris Windows stöder inte POSIX som standard, men Cygwin-miljön tillhandahåller ett POSIX-kompatibilitetslager för Windows. Running externa program. Det är möjligt att anropa externa kommandon från Haskell För att göra det föreslår vi att du använder rawSystem från modulen. Detta kommer att anropa ett specificerat program med angivna argument och returnera exitkoden från det programmet. Du kan spela med det i ghci. Here, vi kör motsvarigheten till shell-kommandot ls - l usr rawSystem analyserar inte argument från en sträng eller utökar jokertecken 43 Istället förväntar vi sig att alla argument ska finnas i en lista Om du inte vill skicka några argument kan du helt enkelt passera en tom lista som denna. katalog och filinformation. Modulen innehåller en hel del funktioner som kan användas för att få information från filsystemet Du kan få en lista med filer i en katalog, byta namn på eller radera filer, kopiera fil s, ändra nuvarande arbetsmapp eller skapa nya kataloger är portabel och fungerar på vilken plattform där GHC fungerar. Bibliotekets referens innehåller en omfattande lista över tillgängliga funktioner Låt oss använda ghci för att visa några av dem De flesta av dessa funktioner Är enkla motsvarigheter till C-bibliotekssamtal eller shellkommandon. Här såg vi kommandon för att ändra den aktuella arbetsmappen och få den nuvarande arbetsmappen från systemet. Dessa liknar cd - och pwd-kommandon i POSIX shell. getDirectoryContents returnerar en lista för varje Objekt i en viss katalog Observera att i POSIX-system innehåller denna lista vanligtvis de speciella värdena och du vill vanligtvis filtrera ut dem när de hanterar innehållet i katalogen, kanske så här. För en mer detaljerad diskussion om filtrering av resultaten av getDirectoryContents se kapitel 8, Effektiv filbehandling, regelbundna uttryck och matchande filnamn. Är filtret inte, Elementet förvirrar Tha t kunde också skrivas som filter c - inte elem c, Backticksna i det här fallet låter oss passera det andra argumentet till notElem Se avsnittet heter Infix funktioner för mer information om backticks. You kan också fråga systemet om platsen för vissa kataloger Den här frågan kommer att ställa in det underliggande operativsystemet för informationen. Programavslutning. Utvecklare skriver ofta enskilda program för att utföra särskilda uppgifter. Dessa enskilda delar kan kombineras för att utföra större uppgifter. Ett skalskript eller ett annat program kan utföra dem. ett sätt att upptäcka om programmet kunde fullfölja uppgiften framgångsrikt Haskell indikerar automatiskt en misslyckad avslutning när ett program avbryts med ett undantag. Det kan dock hända att du kanske behöver mer finkornad kontroll över exitkoden än det kanske du behöver att returnera olika koder för olika typer av fel Modulen ger ett sätt att avsluta programmet och returnera en specifik utgång statuskod till uppringaren Du kan ringa exitWith ExitSuccess för att returnera en kod som indikerar en lyckad avslutning 0 på POSIX-system Eller så kan du ringa något som exitWith ExitFailure 5 som kommer att returnera kod 5 till det anropande programmet. Dates and Times. Allt från filtidstämplar till affärstransaktioner involverar datum och tider Haskell tillhandahåller sätt att manipulera datum och tider, samt funktioner för att erhålla datum och tid information från systemet. ClockTime och CalendarTime. I Haskell är modulen främst ansvarig för datum och tidshantering. Det definierar två typer ClockTime och CalendarTime. ClockTime är Haskell-versionen av den traditionella POSIX-epoken A ClockTime representerar en tid i förhållande till midnatt den 1 januari 1970, UTC En negativ ClockTime representerar ett antal sekunder före det datumet, medan ett positivt tal representerar ett antal sekunder efter det. Klocktid är lämplig för beräkningar Eftersom den spårar Coordinated Universal Time UTC, gör det inte t måste justera för lokala tidszoner, sommartid eller andra speciella fall i tidshantering Varje dag är exakt 60 60 24 eller 86 400 sekunder 44 vilket gör tidsintervallberäkningar enkla. Du kan till exempel kolla klocktiden i början av en lång uppgift, igen i slutet och helt enkelt subtrahera starttiden från sluttiden för att bestämma hur mycket tid som har gått. Du kan sedan dela med 3600 och visa den förflutna tiden som ett antal timmar om du vill. Clock Time är perfekt för att svara på frågor Som dessa. Hur mycket tid har gått. Vad kommer att vara ClockTime 14 dagar före det här exakta ögonblicket. När var filen senast ändrad. Vad är den exakta tiden just nu. Det här är bra användning av ClockTime eftersom de refererar till exakta, Otvetydiga ögonblick i tid Men ClockTime används inte lika enkelt för frågor som. Är det idag måndag. Vilken dag i veckan kommer den 1 maj att falla nästa år. Vad är den aktuella tiden i min lokala tidszon, med potentialen när Daylight är närvarande Sparar tid DST i beaktande. CalendarTime lagrar en tid som människor gör med ett år, månad, dag, timme, minut, sekund, tidszon och DST-information. Det är enkelt att konvertera detta till en bekvämt visningsbar sträng, eller att svara på frågor om lokal tid. Du kan konvertera mellan ClockTime och CalendarTime vid kommer Haskell innehåller funktioner för att konvertera en ClockTime till en CalendarTime i den lokala tidszonen, eller till en kalendertid som representerar UTC. Using ClockTime. ClockTime definieras som här. Den första heltal representerar numret av sekunder sedan epoken Den andra heltal representerar ytterligare ett antal pikosekunder Eftersom ClockTime i Haskell använder den obegränsade heltalstypen kan den effektivt representera ett datumintervall begränsat endast av beräkningsresurser. Låt oss titta på några sätt att använda ClockTime Först finns det getClockTime-funktionen som returnerar den aktuella tiden enligt systemets klocka. Om du väntar en sekund och kör getClockTime igen ser du att den returnerar en uppdaterad tid N otice att utmatningen från det här kommandot var en snygg sträng, komplett med veckodagens information. Det beror på Show-förekomsten för ClockTime. Låt oss titta på ClockTime på en lägre nivå. Vi konstruerar först en ClockTime som representerar den tidpunkt 1000 sekunder efter midnatt den 1 januari 1970, UTC Det ögonblicket kallas epoken Beroende på din tidszon kan det här ögonblicket överensstämma med kvällen den 31 december 1969, i din lokala tidszon. Den andra Exempel visar att vi drar antalet sekunder ut ur det värde som returneras av getClockTime. Vi kan nu manipulera det, som så. Detta visar hur tiden kommer att vara exakt 24 timmar från nu i din lokala tidszon, eftersom det finns 86.400 sekunder på 24 timmar . Använda CalendarTime. As namnet antyder, representerar CalendarTime tid som vi skulle på en kalender. Det har fält för information som år, månad och dag. CalendarTime och dess associerade typer definieras som detta. Det finns några saker om dessa st rukturer som bör markeras. ctWDay ctYDay och ctTZName genereras av biblioteksfunktionerna som skapar en CalendarTime men används inte i beräkningar. Om du skapar en CalendarTime för hand är det inte nödvändigt att sätta exakta värden i dessa fält, såvida inte din senare Beräkningar beror på dem. Alla dessa tre typer är medlemmar i Eq Ord Read and Show typklasser. Dessutom är Månad och dag deklarerad som medlemmar i Enum och Bounded typeklasser. Mer information om dessa typsnitt finns i avsnittet Viktigt Inbyggda typkategorier. Du kan generera CalendarTime-värden på flera sätt. Du kan börja med att konvertera en ClockTime till en CalendarTime som denna. Vi använde getClockTime för att få den aktuella ClockTime från systemets klocka. Nästa, tillCalendarTime omvandlar klocktiden till en kalendertid som representerar Tid i den lokala tidszonen tillUTCtime utför en liknande konvertering, men resultatet är i UTC tidszon istället för den lokala tidszonen E. Notice att toCalendarTime är en IO-funktion, men toUTCTime är inte orsaken till attCalendarTime returnerar ett annat resultat beroende på den lokalt konfigurerade tidszonen, men toUTCTime kommer att returnera exakt samma resultat när det passeras samma källa ClockTime. It s lätt att ändra ett kalendertidvärde. I det här exemplet tog vi först kalendertidsvärdet från tidigare och ändrade helt enkelt sitt år till 1960. Sedan brukade vi toClockTime att konvertera det omodifierade värdet till en ClockTime och sedan det modifierade värdet så att du kan se Skillnad Observera att det modifierade värdet visar ett negativt antal sekunder som en gång har konverterats till ClockTime. Det kan förväntas, eftersom en ClockTime är en kompensation från midnatt den 1 januari 1970, UTC, och det här värdet är 1960. Du kan också skapa CalendarTime värden manuellt. Notera att även om den 15 januari 2010, är ​​det inte söndag - och inte t dag 0 på året - systemet kunde klara det här bara bra. Om vi ​​konverterar värdet till en ClockTime och sedan tillbaka till en CalendarTime hittar du de fälten som fylls korrekt in. TimeDiff för ClockTime. Eftersom det kan vara svårt att hantera skillnader mellan ClockTime-värden på ett mänskligt sätt, innehåller modulen en TimeDiff-typ. TimeDiff kan användas, var bekvämt, Att hantera dessa skillnader Det definieras som detta. Funktioner som diffClockTimes och addToClockTime tar en ClockTime och TimeDiff och hanterar beräkningarna internt genom att konvertera till en CalendarTime i UTC, tillämpa skillnaderna och konvertera tillbaka till en ClockTime. Se s hur det fungerar. Vi startade med att generera en klocktid som representerar midnatt den 5 februari 2008 i UTC Observera att såvida inte din tidszon är densamma som UTC, när den här tiden skrivs ut på skärmen, kan den visa sig som kvällen den 4 februari eftersom den är formaterad för din lokala tidszon. Nästan lägger vi till en månad till det genom att ringa addToClockTime 2008 är ett språngår, men systemet hanterade det ordentligt och vi får ett resultat som har samma datat e och tid i mars Genom att använda toUTCTime kan vi se effekten på detta i den ursprungliga UTC-tidzonen. För ett andra experiment sätter vi upp en tid som representerar midnatt den 30 januari 2009 i UTC 2009 är inte ett språngår, så vi kanske Undra vad som händer när man försöker lägga till en månad till det Vi kan se det, eftersom det inte finns 29 eller 30 december 2009, vi slutar med 2 mars. Först kan vi se hur diffClockTimes ändrar två ClockTime-värden till en TimeDiff men bara sekunder och picoseconds fylls i NormalizeTimeDiff-funktionen tar en sådan TimeDiff och formaterar den som en människa kan förvänta sig att se den. Filändringstider. Många program måste ta reda på när vissa filer senast ändrades Program som ls eller grafiska filhanterare visar typiskt modifieringstiden för filer Modulen innehåller en krypterplattform getModificationTime-funktionen Det tar ett filnamn och returnerar en ClockTime som representerar den tid som filen senast ändrades. Exempelvis. POSIX-plattformar maintai n inte bara en ändringstid som är känd som mtime men också tiden för senaste läs - eller skrivåtkomst vid tidpunkten och tiden för den senaste statusändringen ctime Eftersom denna information är POSIX-specifik, ger plattforms-modulen inte åtkomst till det. Du måste använda funktionerna Här är ett exempel för att göra det. Notice som ringer till getFileStatus som ringer kartor direkt till C-funktionen statens returvärde lagrar ett brett sortiment av information, inklusive filtyp, behörigheter, ägare, grupp, och de tre tidsvärdena vi är intresserade av tillhandahåller olika funktioner, såsom accessTime som extraherar den information vi är intresserade av av den opaka FileStatus-typen som returneras av getFileStatus. Funktionerna som accessTime returnerar data i en POSIX-specifik typ, kallad epokTime som se konvertera till en ClockTime med hjälp av toct-funktionen ger också en setFileTimes-funktion för att ställa in atime och mtime för en fil 45.Extended Example Piping. We har just sett hur man åberopar externt program S Ibland behöver vi mer kontroll över att Kanske vi behöver få utdata från dessa program, tillhandahålla inmatning eller till och med kedja ihop flera externa program. Piping kan hjälpa till med alla dessa behov Piping används ofta i skalskript När du installerar ett rör i skalet körs flera program. Utgången från det första programmet skickas till ingången till den andra. Dess utgång skickas till den tredje som ingång, och så vidare. Det sista programmet s-utgången går normalt till terminalen, eller det kan gå Till en fil Här är ett exempel med POSIX-skalet för att illustrera rörledningar. Detta kommando körs tre program, pipdata mellan dem. Det börjar med ls etc som matar ut en lista över alla filer eller kataloger i osv. Utgången av ls skickas som inmatning Att grep Vi gav grep ett regelbundet uttryck som får det att bara mata ut de linjer som börjar med m och sedan innehålla ap någonstans i linjen Slutligen skickas resultatet av det till tr ​​Vi gav tr alternativ för att konvertera allt till stora versioner. Av tr inte ställas in någonstans, så visas den på skärmen. I den här situationen hanterar skalhandtagen alla rörledningar mellan program. Genom att använda några av POSIX-verktygen i Haskell kan vi uppnå samma sak. Innan du beskriver hur man gör detta bör vi först varna för att modulerna exponerar ett mycket lågt gränssnitt till Unix-system Gränssnittet kan vara komplext och deras interaktioner kan vara komplexa oavsett vilket programmeringsspråk du använder för att komma åt dem Den fulla naturen Av dessa lågnivågränssnitt har varit ämnet för hela böckerna själva, så i det här kapitlet ska vi bara klia på ytan. Använda rör för omdirigering. POSIX definierar en funktion som skapar ett rör Denna funktion returnerar två filbeskrivningar FDs, som liknar I koncept till en Haskell Handle En FD är pipens avläsningsände och den andra är skrivänden. Allt som skrivs till skrivänden kan läsas av avläsningsänden. Data sönder genom ett rör In H Askell, du ringer createPipe för att komma åt det här gränssnittet. Att ha ett rör är det första steget för att kunna pipa data mellan externa program. Vi måste också kunna omdirigera utmatningen av ett program till ett rör och ingången till ett annat program från en röret Haskell-funktionen dupTo åstadkommer detta Det tar en FD och kopierar det till ett annat FD-nummer POSIX FD för standardinmatning, standardutmatning och standardfel har de fördefinierade FD-numren på 0, 1 och 2 respektive genom att numrera en Slutpunkt för ett rör till ett av dessa nummer kan vi effektivt göra att programmen har sina inmatningar eller utgångar omdirigerade. Det finns en annan bit av pusslet, men vi kan inte bara använda dupTo före ett samtal som rawSystem eftersom det skulle röra upp Standardinmatning eller - utmatning i vår huvudsakliga Haskell-process Vidare blockerar rawSystem tills det påberopade programmet körs, vilket ger oss inget sätt att starta flera processer parallellt. För att detta ska kunna ske måste vi använda forkProcess Detta är en mycket speciell Funktion Det gör faktiskt en kopia av det aktuella programmet och du slutar med två exemplar av programmet som körs samtidigt. Haskell s forkProcess-funktion tar en funktion att utföra i den nya processen som kallas barnet Vi har det funktionssamtalet dupTo Efter det har det gjort det kallas executeFile för att faktiskt åberopa kommandot Detta är också en speciell funktion om allt går bra, det returnerar aldrig det s eftersom executeFile ersätter körprocessen med ett annat program Till sist kommer den ursprungliga Haskell-processen att ringa getProcessStatus till Vänta på att barnet processerar att avsluta och lära av sina exitkoder. När du kör ett kommando på POSIX-system, oavsett om du bara har skrivit ls på kommandoraden eller använt rawSystem i Haskell, under huven, gaffelprocess executeFile och getProcessStatus eller deras C ekvivalenter används alltid för att ställa in rör, duplicerar vi processen som systemet använder för att starta program och lägger till några steg med rörledning och Omdirigering längs vägen. Det finns några andra hushållssaker vi måste vara försiktiga om. När du ringer forkProcess är det bara om allt om ditt program klonat 46. Det inkluderar uppsättningen öppna filbeskrivningshandtag Program upptäcker när de är färdiga att ta emot ingång från ett rör genom att kontrollera slutindikatorns indikator När processen vid den rörliga änden av ett rör stänger röret, kommer processen vid läsänden att få en slutändningsindikering. Om skrivningsfilbeskrivningen finns i mer än en Process, slutänden indikatorn vunnits t skickas tills alla processer har stängt den specifika FD Därför måste vi hålla reda på vilka FD som öppnas så att vi kan stänga alla i barnets processer. Vi måste också stänga barnets slut på Rören i förälderprocessen så snart som möjligt. Här är en initial implementering av ett system av rörsystem i Haskell. Vi experimenterar med detta i ghci lite innan vi tittar på hur det fungerar. Vi börjar med att köra ett enkelt kommando, pwd wh Jag skriver bara namnet på den aktuella arbetsboken. Vi skickar för listan över argument, eftersom pwd behöver inte några argument. På grund av de typsnitt som används kan Haskell inte härleda typen så vi specifikt nämner att det är String. Då får vi till mer komplexa kommandon Vi kör och skickar det genom grep I slutet sätter vi ett rör för att springa exakt samma kommando som vi sprang via ett skalbyggt rör i början av det här avsnittet. Det är inte så trevligt som det var i skalet, men då är vårt program fortfarande relativt enkelt jämfört med skalet. Låt oss titta på programmet Den allra första raden har en speciell OPTIONSGHC-klausul Detta är detsamma som att passera - fglasgow-exts till ghc eller ghci Vi är med hjälp av en GHC-förlängning som tillåter oss att använda en String, String-typ som en förekomst av ett typsnitt 47 Genom att sätta det i källfilen måste vi inte komma ihåg att ange det varje gång vi använder den här modulen. Efter importlinjerna, vi definierar några typer Först definierar vi typ SysCommand String, S Tring som ett alias Detta är typen ett kommando som ska utföras av systemet kommer att ta Vi använde data av den här typen för varje kommando i exekveringsexemplet ovan Kommandrelsestypen representerar resultatet från att utföra ett visst kommando och typen CloseFDs representerar Lista över FD som vi måste stänga när vi förkortar ett nytt barnprocess. Nästan definierar vi en klass med namnet CommandLike Denna klass kommer att användas för att köra saker, där en sak kan vara ett fristående program, ett rör som sätts upp mellan två eller flera program, eller i framtiden, även rena Haskell-funktioner. För att vara medlem i den här klassen behöver endast en funktion - anropa - vara närvarande för en given typ. Det låter oss använda runIO för att starta antingen ett fristående kommando eller en pipeline. också vara användbar för att definiera en pipeline, eftersom vi kan ha en hel stapel kommandon på en eller båda sidor av ett givet kommando. Vår rörinfrastruktur kommer att använda strängar som sätt att skicka data från en process till en annan. Vi kan utnyttja av Haskell s Stöd för lat läsning via hGetContents medan du läser data och använd forkIO för att låta skrivning ske i bakgrunden. Detta fungerar bra, men inte så snabbt som att koppla samman två processers ändpunkter direkt. 48 Det gör genomförandet ganska enkelt, men vi behöver bara ta bryr sig om att göra ingenting som skulle kräva att hela strängen buffras och låt Haskell s lathet göra resten. Näst definierar vi en förekomst av CommandLike för SysCommand Vi skapar två rör en som ska användas för den nya processens standardinmatning och Andra för sin standardutmatning Det skapar fyra ändpunkter och därmed fyra filbeskrivningar Vi lägger till föräldrelfilbeskrivarna till listan över de som måste stängas i alla barn. Det här skulle vara skrivänden för barnets standardinmatning och läsänden Av barnets standardutmatning Nästa, vi gafflar barnprocessen I föräldern kan vi sedan stänga filbeskrivningarna som motsvarar barnet. Vi kan inte göra det före gaffeln, för då skulle de inte Vara tillgänglig för barnet Vi får ett handtag för stdinwrite-filbeskrivaren och starta en tråd via forkIO för att skriva indata till den. Vi definierar sedan waitfunc vilken är den åtgärd som uppringaren kommer att påkalla när den är redo att vänta på den uppringda Process att avsluta Under tiden använder barnet dupTo stänger de filbeskrivningar som det inte behöver, och kör kommandot. Nästa definierar vi några verktygsfunktioner för att hantera listan med filbeskrivningar. Därefter definierar vi de verktyg som hjälper till att ställa upp ledningar först , Definierar vi en ny typ PipeCommand som har en källa och destination. Både källan och destinationen måste vara medlemmar i CommandLike. Vi definierar också - - - operatören. Sedan gör vi PipeCommand till en instans av CommandLike. Genom att implementera startar det första kommandot med den givna Inmatas, får sin utgång och skickar den till utgången till det andra kommandot. Det returnerar sedan utgången från det andra kommandot och får funktionen getExitStatus att vänta För och kontrollera exitstatuserna från båda kommandona. Vi avslutar med att definiera runIO Denna funktion fastställer listan över FD som måste stängas i klienten, startar kommandot, visar dess utgång och kontrollerar utgångsstatus. Bättre pipning.

No comments:

Post a Comment