Thursday 9 November 2017

Haskell Trading System


Velkommen til Hackage. Hackage er Haskell-fellesskapets sentrale pakkearkiv for åpen kildekode. Pakkeforfattere bruker det til å publisere sine biblioteker og programmer mens andre Haskell-programmerere bruker verktøy som cabal-install for å laste ned og installere pakker eller folk får pakkene via deres distro . Dette webgrensesnittet til Hackage lar deg. Browse pakkene sortert etter kategori. Søk etter pakker med søkeord i navnet eller beskrivelsen. Se hvilke pakker som har blitt lastet opp nylig. Last opp dine egne pakker til Hackage notat at du trenger en konto. pakken inneholder en beskrivelse av hva den gjør. Informasjon om informasjon. Author information. A nedlastbar gzipped tarball. En liste over moduler i pakken. Haddock dokumentasjon hvis tilgjengelig med kilde links. Guidelines for Hackage Packages. All pakker bør følge pakken Versjonspolitikk PVP. Packages kan ikke slettes, så du bør vurdere å laste opp nye versjoner pakker som en pakke kandidat og testing før publisering den til hovedindeks. I tillegg til hovedpakken listesiden, er det noen andre pakkeindekser. Administrative issues. Reporting problems. For problemer med kontoer eller tillatelser, vennligst kontakt administratorer via e-post på. For feil med nettstedskoden eller server hosting problemer , vær så snill å rapportere dem i spørsmålet vårt Tracker. Contributing to the development. The koden er på github og vi ønsker velkommen forespørsler. Det er åpne billetter som beskriver eksisterende feil og funksjoner som vi vil ha eller som trenger forbedring. Hjelp på noen av disse ville bli verdsatt. Det er noen utvikler og brukerdokumentasjon på github wiki, inkludert en rask guide for å få din egen server forekomst oppe og går. Du kan stille spørsmål på cabal-devel mailinglisten eller på IRC i hackage-kanalen på freenode. Den nye serveren har et automatisk generert nettsted api. Dette er hovedsakelig ment som dokumentasjon for personer som arbeider med serveren, i stedet for som brukerorientert nettstedskart, men det kan være interessant å se e eksakt hva som er tilgjengelig Dette inkluderer viktige ressurser som maskinlesbar indeks av pakker som brukes av klienter som cabal-install. Well-Typed og Industrial Haskell Group IHG er veldig fornøyd med å kunngjøre at Hackage 2 nå driver den offisielle Hackage-serveren. Les videre for en oversikt over de nye funksjonene, systemforbedringene og for detaljer om hvordan du kan bidra til å gjøre Hackage 2 enda bedre. Støtte fra Industrial Haskell Group. IHG er et konsortium av selskaper som er avhengige av Haskell. IHG-medlemmene har finansiert innsatsen for å få Hackage 2 til å fungere paritet og gjøre den klar for overgangen. IHG finansierte denne innsatsen fordi mens frivillighetsinnsatsen fikk oss den første 90 måten der, inkludert å legge til en rekke nye funksjoner, var det fortsatt de siste 90 å gjøre for å gjøre produksjonen klar. IHG-medlemmene bestemte seg for å finansiere Hackage 2, ikke bare fordi de er gode borgere, men ut av opplyst egeninteresse. Hackage har over 5000 pakker skrevet av over 1000 personer le inkludert verdens beste Haskell-utviklere Dette er en enorm ressurs IHG-medlemmene innser at forbedringer av verktøy og infrastruktur som samfunnet bruker, hjelper samfunnet til å produsere mer og bedre kode Dette er en fordel for alle i samfunnet, inkludert de kommersielle brukerne. HHG er ivrig etter å øke sitt medlemskap slik at flere ressurser kan være dedikert til å forbedre Haskell-utviklingsplattformen Hvis din organisasjon er avhengig av Haskell på en eller annen måte, vil du kanskje vurdere å bli med på IHGs hjemmeside for mer informasjon eller kontakt. hjelp av IHG ved å komme til dette punktet, er Hackage et fellesskapsprosjekt, og suksessen avhenger av samfunnet, og opprettholder og forbedrer den nye serveren. Koden er nå på github, slik at det er lettere å bidra, og nå at serveren er live Det er mer umiddelbar tilfredsstillelse for frivillige som bidrar til reparasjoner og nye funksjoner. Det raskeste innholdsdistribusjonsnettverket. Som behovene til fellesskapet er det Hackage og andre deler av vår infrastruktur krever økende mengder båndbredde, lavere ventetid og mer lagrings - og beregne ressurser. Hackage inneholder kode skrevet fra folk over hele verden, og oppetid og hastighet er avgjørende for en ren brukeropplevelse når du utvikler . har tilbudt samfunnet ubegrenset tilgang til deres CDN, slik at vi kan presse TB-data gjennom deres kantsystemer, gi ressursbeskyttelse for servere, og få sanntidsanalyser for alle våre brukere og data. Nye funksjoner. Selv om vår hovedprioritet har vært funksjonalitet slik at vi kan bytte over, har frivillige bidratt til flere nye funksjoner, inkludert bedre pakkesøk, et nytt nettstedstema, forbedret sikkerhet, muligheten til å fikse pakkeavhengigheter etter en utgivelse, endringslogger og et REST-stil-grensesnitt. Se på nye funksjoner side for mer informasjon om disse, samt detaljer om andre funksjoner som er delvis implementert eller trenger forbedring. så gjør vi dette oppdraget på Uni og jeg har et seriøst ønske om å gjøre oppdraget i haskell. Det er en simulering av en aksjehandel motor Situasjon er at vi har data som kommer inn fra et csv og vi ønsker å analysere hver post og behandle den på en bestemt måte avhengig av hvilken markedsfase den tildeles til Begrunnelse for bruk av haske Det er jeg som ser på tradingmotoren som et tungt funksjonelt system. Jeg har hatt haskell-erfaring før, men bare mindre erfaring, aldri noe så stort. Vi ønsket å kjøre en tråd som ville importere CSVene til en kø med ubehandlede ordrer og deretter ha hovedprogrammet tilgang til denne køen for å behandle hver ordre. Men hvordan kunne jeg oppnå dette jeg kjenner i C, ville jeg bare sette opp klassen slik at den kunne få tilgang til CSVParser-klassen som ville holde den ubehandlede køen. Dette betyr også at importtråden ville være kontinuerlig å kjøre gjennom alle markedsfasene eller til den er ferdig med å importere csv-filen. En ny veiledning om hvordan man oppnår dette ville være flott, ikke å lete etter et fullt skrevet skript, bare hvilke ting i haskell jeg måtte se på. Skrevet 29. mars 12 klokka 23 33. lukket som ikke et reelt spørsmål av Ritch Melton dflemstr Flexo Michael Petrotta Graviton Mar 30 12 på 1 45. Det er vanskelig å fortelle hva som blir spurt her Dette spørsmålet er tvetydig, vag, ufullstendig, altfor bred eller retorisk og kan ikke besvares rimelig i sin nåværende form For hjelp med å avklare dette spørsmålet slik at det kan gjenåpnes, besøk brukerstøtten. Hvis dette spørsmålet kan omformuleres for å passe til reglene i brukerstøtten, kan du redigere spørsmålet. Innholdsfortegnelse. langt har vi snakket mest om konsept på høyt nivå Haskell kan også brukes til programmering på lavere nivå Det er ganske mulig å skrive programmer som grensesnittet til operativsystemet på lavt nivå ved hjelp av Haskell. I dette kapitlet skal vi å forsøke noe ambisiøst et Perl-lignende språk som er gyldig Haskell, implementert i ren Haskell, som gjør shell-skripting enkelt. Vi skal implementere rør, enkel kommandoangrep og noen enkle verktøy for å håndtere oppgaver som ellers kunne utføres med grep eller sed. Spesialiserte moduler finnes for forskjellige operativsystemer I dette kapitlet vil vi bruke generiske OS-uavhengige moduler så mye som mulig. Vi vil imidlertid fokusere på POSIX-miljøet fo r mye av kapittelet POSIX er en standard for Unix-lignende operativsystemer som Linux, FreeBSD, MacOS X eller Solaris Windows støtter ikke POSIX som standard, men Cygwin-miljøet gir et POSIX-kompatibilitetslag for Windows. Running eksterne programmer. Det er mulig å påberope eksterne kommandoer fra Haskell. For å gjøre det, foreslår vi at du bruker RawSystem fra modulen. Dette vil påkalle et spesifisert program med de angitte argumentene og returnere utgangskoden fra det programmet. Du kan spille med det i ghci. Her, vi kjører ekvivalenten av shell kommandoen ls - l usr rawSystem analyserer ikke argumenter fra en streng eller utvider wildcards 43 I stedet forventer det at hvert argument skal være inneholdt i en liste. Hvis du ikke vil passere noen argumenter, kan du bare passere en tom liste som denne. Directory og File Information. Modulen inneholder ganske mange funksjoner som kan brukes til å skaffe informasjon fra filsystemet. Du kan få en liste over filer i en katalog, omdøpe eller slette filer, kopiere fil s, endre gjeldende arbeidskatalog, eller opprett nye kataloger, er bærbare og fungerer på alle plattformer hvor GHC fungerer. Bibliotekets referanse gir en omfattende liste over tilgjengelige funksjoner La oss bruke ghci til å demonstrere noen av dem De fleste av disse funksjonene er rettverdige ekvivalenter til C-bibliotekssamtaler eller shellkommandoer. Her så vi kommandoer for å endre den nåværende arbeidskatalogen og hente den nåværende arbeidskatalogen fra systemet. Disse ligner cd - og pwd-kommandoene i POSIX shell. getDirectoryContents returnerer en liste for hver element i en gitt katalog Merk at i POSIX-systemer inneholder denne listen normalt spesielle verdier, og du vil vanligvis filtrere disse ut når du behandler innholdet i katalogen, kanskje som dette. For en mer detaljert diskusjon om filtrering av resultatene av getDirectoryContents se kapittel 8, Effektiv filbehandling, vanlige uttrykk og filnavn som matcher. Er filteret ikke Element, forvirrende del Tha t kunne også bli skrevet som filter c - ikke elem c, Backticks i dette tilfellet lar oss effektivt passere det andre argumentet til notElem se delen Infald funksjoner for mer informasjon om backticks. You kan også spørre systemet om plasseringen av bestemte kataloger Denne spørringen vil spørre det underliggende operativsystemet for informasjonen. Programavslutning. Utviklere skriver ofte enkelte programmer for å utføre bestemte oppgaver. Disse individuelle delene kan kombineres for å utføre større oppgaver. Et skallskript eller et annet program kan utføre dem. en måte å finne ut om programmet var i stand til å fullføre oppgaven sin Vellykket Haskell angir automatisk en ikke-vellykket avslutning når et program blir avbrutt av et unntak. Men det kan hende du trenger mer finkornet kontroll over utgangskoden enn det Kanskje du trenger å returnere forskjellige koder for ulike typer feil Modulen gir en måte å avslutte programmet og returnere en bestemt utgang statuskode til innringeren Du kan ringe exitWith ExitSuccess for å returnere en kode som indikerer en vellykket avslutning 0 på POSIX-systemer Eller du kan ringe noe som exitWith ExitFailure 5 som returnerer kode 5 til det ringende programmet. Dater og tider. Alt fra filtidstempler til forretningstransaksjoner involverer datoer og tider Haskell gir måter å manipulere datoer og tider, samt funksjoner for å skaffe dato og klokkeslettinformasjon fra systemet. Klokkeslett og kalendertid. I Haskell er modulen primært ansvarlig for dato - og tidshåndtering. Det definerer to typer ClockTime og CalendarTime. ClockTime er Haskell-versjonen av den tradisjonelle POSIX-epoken. A ClockTime representerer en tid i forhold til midnatt 1. januar 1970, UTC. En negativ ClockTime representerer et antall sekunder før den datoen, mens et positivt tall representerer et antall sekunder etter det. Clock Time er praktisk for beregninger Siden det sporer Koordinert Universal Time UTC, gjør det ikke t må justere for lokale tidssoner, sommertid eller andre spesielle tilfeller i tidshåndtering Hver dag er nøyaktig 60 60 24 eller 86 400 sekunder 44 som gjør tidsintervallberegninger enkle. Du kan for eksempel sjekke ClockTime ved starten av en lang oppgave, igjen på slutten og bare trekke starttidspunktet fra sluttidspunktet for å bestemme hvor mye tid som har gått. Du kan da dele ved 3600 og vise den forløpte tiden som en timeromgang hvis du ønsker. Clock Time er ideell for å svare på spørsmål slik som disse. Hvor mye tid har gått. Hva vil være ClockTime 14 dager foran dette nøyaktige øyeblikk. Når ble filen sist endret. Hva er den nøyaktige tiden akkurat nå. Disse er gode bruksområder av ClockTime fordi de refererer til presise, Uklare øyeblikk i tid Men ClockTime er ikke like lett brukt til spørsmål som. Den er i dag mandag. Hvilken dag i uken vil 1. mai falle på neste år. Hva er den nåværende tiden i min lokale tidssone, og tar den potensielle tilstedeværelsen av dagslys Lagringstid DST hensyn. CalendarTime lagrer en tid som mennesker gjør med et år, måned, dag, time, minutt, sekund, tidszone og DST-informasjon. Det er enkelt å konvertere dette til en beleilig utstillbar streng, eller å svare på spørsmål om lokal tid. Du kan konvertere mellom ClockTime og CalendarTime ved vil Haskell inneholder funksjoner for å konvertere en ClockTime til en CalendarTime i den lokale tidssonen, eller til en kalendertid som representerer UTC. Using ClockTime. ClockTime er definert som dette. Den første helheten representerer tallet av sekunder siden epoken Den andre helheten representerer et ekstra antall pikosekunder Fordi ClockTime i Haskell bruker den ubundne heltalstypen, kan den effektivt representere et datoperiode som bare er begrenset av beregningsmessige ressurser. Vi ser på noen måter å bruke ClockTime Først er det GetClockTime-funksjonen som returnerer gjeldende tid i henhold til systemets klokke. Hvis du venter et sekund og kjører getClockTime igjen, vil du se at det returnerer en oppdatert tid N otice at utgangen fra denne kommandoen var en fin snor, komplett med ukentlig informasjon Det skyldes Show-forekomsten for ClockTime La oss se på ClockTime på et lavere nivå. Her konstruerer vi først en ClockTime som representerer punkt i tid 1000 sekunder etter midnatt 1. januar 1970, UTC Det øyeblikket er kjent som epoken Avhengig av tidszonen din, kan dette tidspunktet svare til kvelden 31. desember 1969, i din lokale tidszone. Den andre eksempel viser at vi trekker antall sekunder ut av verdien returnert av getClockTime. Vi kan nå manipulere det, slik. Dette vil vise hvordan tiden vil være nøyaktig 24 timer fra nå i din lokale tidssone, siden det er 86,400 sekunder om 24 timer. bruker kalendertid. As navnet antyder, representerer calendartime tiden som vi ville på en kalender. Det har felt for informasjon som år, måned og dag. Calendartime og tilhørende typer er definert som dette. Det er noen ting om disse st rukturer som skal utheves. ctWDay ctYDay og ctTZName genereres av biblioteksfunksjonene som lager en CalendarTime, men brukes ikke i beregninger Hvis du oppretter en CalendarTime for hånd, er det ikke nødvendig å sette nøyaktige verdier inn i disse feltene, med mindre du senere beregninger vil avhenge av dem. Alle disse tre typene er medlemmer av Eq Ord Read and Show typeklasser. I tillegg er Måned og dag deklarert som medlemmer av Enum og Bounded typeklasser. For mer informasjon om disse typeklassene, se avsnittet Viktig Innebygde typeklasser. Du kan generere CalendarTime-verdier på flere måter. Du kan starte med å konvertere en ClockTime til en CalendarTime som dette. Vi brukte getClockTime for å hente den nåværende ClockTime fra systemets klokke. Next, toCalendarTime konverterer ClockTime til en CalendarTime som representerer Tid i den lokale tidszonen tilUTCtime utfører en lignende konvertering, men resultatet er i UTC tidszonen i stedet for den lokale tidssonen e. Notice at toCalendarTime er en IO-funksjon, men toUTCTime er ikke Årsaken er at toCalendarTime returnerer et annet resultat avhengig av den lokalt konfigurerte tidssonen, men toUTCTime vil returnere nøyaktig samme resultat når det er bestått samme kilde ClockTime. It s Lett å endre en kalendertidsverdi. I dette eksemplet tok vi først kalendertidsverdien fra tidligere og bare byttet år til 1960. Så brukte vi toClockTime til å konvertere den umodifiserte verdien til en ClockTime og deretter den endrede verdien slik at du kan se forskjell Legg merke til at den endrede verdien viser et negativt antall sekunder en gang konvertert til ClockTime Det kan forventes, siden en ClockTime er en kompensasjon fra midnatt 1. januar 1970, UTC, og denne verdien er i 1960. Du kan også opprette CalendarTime verdier manuelt. Merk at selv om 15. januar 2010, er ikke søndag - og ikke t dag 0 i året - var systemet i stand til å behandle dette helt fint. Faktisk, hvis vi konverterer verdien til en ClockTime og så tilbake til en CalendarTime finner du de feltene som er riktig fylt in. TimeDiff for ClockTime. Fordi det kan være vanskelig å håndtere forskjeller mellom ClockTime-verdier på en menneskelig måte, inkluderer modulen TimeDiff-typen TimeDiff kan brukes, hvor praktisk, å håndtere disse forskjellene Det er definert som dette. Funksjoner som diffClockTimes og addToClockTime tar en ClockTime og TimeDiff og håndterer beregningene internt ved å konvertere til en CalendarTime i UTC, bruke forskjellene, og konvertere tilbake til en ClockTime. Let se hvordan det virker. Vi startet med å generere et klokkeslett som representerer midnatt 5. februar 2008 i UTC Merk at, med mindre tidszonen er den samme som UTC, når denne tiden skrives ut på skjermen, kan det dukke opp som om kvelden den 4. februar fordi det er formatert for din lokale tidssone. Nesten legger vi en måned til det ved å ringe addToClockTime 2008 er et sprangår, men systemet håndteres riktig og vi får et resultat som har samme datat e og tid i mars Ved å bruke toUTTime kan vi se effekten på dette i den opprinnelige UTC-tidssonen. For et annet eksperiment, setter vi opp en tid som representerer midnatt den 30. januar 2009 i UTC 2009 er ikke et sprangår, så vi kan lurer på hva som vil skje når du prøver å legge til en måned til det Vi kan se det, siden det ikke finnes 29 eller 30 februar i 2009, slutter vi opp med 2. mars. Til slutt kan vi se hvordan diffClockTimes gjør to ClockTime-verdier til en TimeDiff, men bare sekunder og pikosekunder er fylt inn NormalizeTimeDiff-funksjonen tar en slik TimeDiff og reformaterer den som et menneske kan forvente å se det. Filmodifikasjonstider. Mange programmer må finne ut når bestemte filer sist ble endret Programmer som ls eller grafiske filbehandlere viser vanligvis modifikasjonstiden for filer Modulen inneholder en krypterplattform getModificationTime-funksjon Det tar et filnavn og returnerer en ClockTime som representerer tiden filen ble sist endret For eksempel. POSIX-plattformer n ikke bare en modifikasjonstid kjent som mtime, men også tidspunktet for siste lesing eller skrivingstidspunkt og tidspunktet for siste statusendring ctime Siden denne informasjonen er POSIX-spesifikk, gir ikke plattformmodulen tilgang til den I stedet, du må bruke funksjoner i Her er et eksempelfunksjon for å gjøre det. Notat som ringer til getFileStatus som ringer kart direkte til C-funksjonen statens returverdi lagrer et stort utvalg av informasjon, inkludert filtype, tillatelser, eier, gruppe, og de tre tidsverdiene vi er interessert i, gir forskjellige funksjoner, for eksempel accessTime, som trekker ut informasjonen vi er interessert ut av den ugjennomsiktige FileStatus-typen returnert av getFileStatus. Funksjonene som accessTime-returdata i en POSIX-spesifikk type kalt epokTime som se konvertere til en ClockTime ved hjelp av toct-funksjonen, gir også en setFileTimes-funksjon for å sette atime og mtime for en fil 45.Extended Example Piping. We har nettopp sett hvordan å påberope eksternt program s Noen ganger trenger vi mer kontroll over at Kanskje vi trenger å få utdata fra disse programmene, gi innspill eller til og med kjede sammen flere eksterne programmer. Rørledning kan hjelpe til alle disse behovene. Røring brukes ofte i skalskript Når du setter opp et rør i skallet kjører du flere programmer Utgangen av det første programmet sendes til inngangen til det andre. Utgangen sendes til den tredje som inngang, og så videre. Det siste programets utgang går normalt til terminalen, eller det kan gå til en fil Her er et eksempel økt med POSIX-skallet for å illustrere rørledninger. Denne kommandoen kjører tre programmer, pipedata mellom dem. Det starter med ls etc som utfører en liste over alle filer eller kataloger i osv. Utgangen av ls sendes som input å grep Vi ga grep et regulært uttrykk som vil føre til at det bare utleder linjene som starter med m og deretter inneholder ap et sted i linjen Til slutt blir resultatet av det sendt til tr Vi ga tr alternativer for å konvertere alt til store versjoner. Utgangenav tr ern t satt hvor som helst spesielt, så det vises på skjermen. I denne situasjonen håndterer skallet alle rørledninger mellom programmer. Ved å bruke noen av POSIX-verktøyene i Haskell kan vi oppnå det samme. Før du beskriver hvordan du gjør dette, bør vi først advare deg om at modulene avslører et veldig lavt grensesnitt til Unix-systemer Grensesnittene kan være komplekse og deres interaksjoner kan også være komplekse, uansett hvilket programmeringsspråk du bruker for å få tilgang til dem. Den fulle naturen av disse grensesnittene på lavt nivå har vært temaet for hele bøkene selv, så i dette kapitlet vil vi bare klø på overflaten. Bruke Rør for omdirigering. POSIX definerer en funksjon som lager et rør Denne funksjonen returnerer to filbeskrivelser FDs, som ligner i konsept til en Haskell-håndtak En FD er avlesningsenden av røret, og den andre er skriveenden. Alt som er skrevet til skriveenden, kan leses av avlesningsenden. Dataene skubbes gjennom et rør i H askell, du kaller createPipe for å få tilgang til dette grensesnittet. Å holde et rør er det første trinnet for å kunne pipe data mellom eksterne programmer. Vi må også kunne omdirigere utgangen av et program til et rør, og inngangen til et annet program fra en pipe Haskell-funksjonen dupTo oppnår dette Det tar en FD og gjør en kopi av den til et annet FD-nummer POSIX FDs for standardinngang, standardutgang og standardfeil har de forhåndsdefinerte FD-tallene henholdsvis 0, 1 og 2 Ved å omnummerere en endepunkt for et rør til et av disse tallene, kan vi effektivt føre til at programmene har inngang eller utdata omdirigert. Det er et annet stykke av puslespillet, men vi kan ikke bare bruke dupTo før en samtale som rawSystem fordi dette ville ødelegge standardinngang eller - utgang i vår viktigste Haskell-prosess Videre blokkeres rawSystem til det påkrevde programmet kjøres, og gir oss ingen mulighet til å starte flere prosesser som kjører parallelt. For å gjøre dette skje, må vi bruke forkProcess Dette er en veldig spesiell funksjon Det gjør faktisk en kopi av det for tiden kjørte programmet, og du slutter med to kopier av programmet som kjører samtidig. Haskell s forkProcess-funksjon tar en funksjon å utføre i den nye prosessen kjent som barnet Vi har det funksjonssamtalen dupTo Etter at det har gjort det, kalles det executeFile for å faktisk påkalle kommandoen. Dette er også en spesialfunksjon hvis alt går bra, det returnerer aldri Det er fordi executeFile erstatter kjøringsprosessen med et annet program Til slutt vil den opprinnelige Haskell-prosessen kalte getProcessStatus til vent på at barnet prosesser for å avslutte og lære av utgangskoder. Når du kjører en kommando på POSIX-systemer, enten du bare har skrevet ls på kommandolinjen eller brukt rawSystem i Haskell, under hetten, gaffelprosess executeFile og getProcessStatus eller deres C ekvivalenter blir alltid brukt For å sette opp rør dupliserer vi prosessen som systemet bruker til å starte opp programmer, og legge til noen få trinn som involverer rør og omdirigering underveis. Det er noen andre housekeeping ting vi må være forsiktig med når du ringer forkProcess omtrent alt om programmet ditt er klonet 46 som inkluderer settet med åpne filbeskrivelseshåndterer Programmer oppdager når de blir ferdig med å motta inngang fra et rør ved å sjekke end-of-file-indikatoren Når prosessen ved den skriveende enden av et rør lukker røret, vil prosessen ved avlesningsenden motta en end-of-fil-indikasjon. Men hvis skrivefilbeskrivelsen eksisterer i mer enn en prosess, vil slutten av filindikatoren vunnet t sendes inntil alle prosesser har lukket den bestemte FD Derfor må vi holde rede på hvilke FD'er som er åpnet, slik at vi kan lukke dem alle i barnet prosesser. Vi må også lukke barnets ender av rørene i overordnet prosess så snart som mulig. Her er en innledende implementering av et rørsystem i Haskell. Let s eksperimentere med dette i ghci litt før du ser på hvordan det fungerer. Vi starter med å kjøre en enkel kommando, pwd wh Jeg skriver bare navnet på den nåværende arbeidskatalogen. Vi passerer for listen over argumenter, fordi pwd ikke trenger noen argumenter. På grunn av de brukte typeklassene, kan Haskell ikke utlede typen slik at vi spesifikt nevner at det er String. Så får vi inn i mer komplekse kommandoer Vi kjører Jeg sender den gjennom grep På slutten setter vi opp et rør for å løpe nøyaktig samme kommando som vi løp via et skallbygd rør i begynnelsen av denne delen. Det er ikke så hyggelig som det var i skallet, men igjen er vårt program fortsatt relativt enkelt sammenlignet med skallet. Vi ser på programmet. Den aller første linjen har en spesiell OPTIONSGHC-klausul. Dette er det samme som å passere - fglasgow-exts til ghc eller ghci. Vi er ved hjelp av en GHC-utvidelse som tillater oss å bruke en streng, strengtype som en forekomst av en typeclass 47 Ved å sette den i kildefilen må vi ikke huske å spesifisere det hver gang vi bruker denne modulen. Etter importlinjene, Vi definerer noen få typer Først definerer vi type SysCommand String, S tring som et alias Dette er typen en kommando som skal utføres av systemet vil ta Vi brukte data av denne typen for hver kommando i eksekveringseksempelet ovenfor. KommandoResultat-typen representerer resultatet fra å utføre en gitt kommando, og typen CloseFDs representerer liste over FD'er som vi må lukke ved å forkaste en ny barneprosess. Nesten definerer vi en klasse som heter CommandLike Denne klassen vil bli brukt til å kjøre ting, hvor en ting kan være et frittstående program, et rør satt opp mellom to eller flere programmer, eller i fremtiden, til og med rene Haskell-funksjoner. For å være medlem i denne klassen, må bare en funksjon - påkalle - være tilstede for en gitt type. Dette vil la oss bruke runIO til å starte enten en frittstående kommando eller en rørledning. Det vil kan også være nyttig for å definere en rørledning, siden vi kan ha en hel gruppe kommandoer på en eller begge sider av en gitt kommando. Vår rørinfrastruktur skal bruke strenge som vei for å sende data fra en prosess til en annen. Vi kan dra nytte av av Haskell s støtte for lat lesing via hGetContents mens du leser data, og bruk forkIO for å la skrive oppstå i bakgrunnen. Dette vil fungere bra, men ikke så fort som å koble endepunktene til to prosesser direkte sammen. 48 Det gjør implementeringen ganske enkel, men vi trenger bare ta vær forsiktig med å gjøre noe som vil kreve at hele strengen blir buffret, og la Haskell's latskap gjøre resten. Nedenfor definerer vi en forekomst av CommandLike for SysCommand Vi lager to rør en til bruk for den nye prosessens standardinngang, og andre for sin standardutgang Dette skaper fire endepunkter og dermed fire filbeskrivelser Vi legger til de overordnede filbeskrivelsene til listen over de som må lukkes i alle barn Dette ville være skriveenden til barnets standardinngang, og leseenden av barnets standardutgang Neste, vi gaffel barnprosessen I foreldre kan vi deretter lukke filbeskrivelsene som svarer til barnet. Vi kan ikke gjøre det før gaffelen, for da ville de ikke være tilgjengelig for barnet Vi oppnår et håndtak for stdinwrite-filbeskrivelsen og starter en tråd via forkIO for å skrive inndataene til den. Deretter definerer du waitfunc hvilken handling den oppringer vil påkalle når den er klar til å vente på den kalt prosess å avslutte I mellomtiden bruker barnet dupTo lukker filbeskrivelsene det ikke trenger, og kjører kommandoen. Nedenfor definerer vi noen bruksfunksjoner for å administrere listen over filbeskrivere. Deretter definerer vi verktøyene som hjelper til med å sette opp rørledninger først , definerer vi en ny type PipeCommand som har en kilde og en destinasjon. Både kilden og destinasjonen må være medlem av CommandLike. Vi definerer også - - bekvemmelighetsoperatøren. Deretter lager vi PipeCommand en forekomst av CommandLike. Den påberoperte implementeringen starter den første kommandoen med gitt input, får sin utgang, og overfører den til utgangen til den andre kommandoen. Den returnerer deretter utgangen av den andre kommandoen, og får funksjonen getExitStatus til å vente for og sjekke utgangsstatusene fra begge kommandoene. Vi avslutter ved å definere runIO Denne funksjonen etablerer listen over FD'er som må lukkes i klienten, starter kommandoen, viser utgangen og kontrollerer utgangsstatusen. Better piping.

No comments:

Post a Comment