Friday 22 December 2017

Haskell sistema de negociação


Bem-vindo ao Hackage. Hackage é o arquivo de pacote central da comunidade de Haskell do software de fonte aberta Os autores de pacote o usam para publicar suas bibliotecas e programas enquanto outros programadores de Haskell usam ferramentas como cabal-install para baixar e instalar pacotes ou pessoas obtêm os pacotes via sua distro . Esta interface web para Hackage permite you. Browse os pacotes classificados por categoria. Search para pacotes por palavra-chave no nome ou description. See que pacotes foram enviados recentemente. Upload seus próprios pacotes para Hackage nota que você ll precisa de uma conta. Cada Pacote inclui. Uma descrição do que ele faz. Licença de informação. Author informações. Uma lista tarball. gzip. gzip download. Uma lista de módulos na documentação package. Haddock se disponível com fonte links. Guidelines para Pacotes Hackage. Todos os pacotes devem seguir a Política de Versão de Pacotes PVP. Packages não podem ser excluídos, portanto você deve considerar fazer o upload de novos pacotes de versões como um candidato a um pacote e testá-los antes de publicá-los no Principal índice. Além da página da lista de pacotes principais, existem alguns outros índices de pacotes. Problemas administrativos. Problemas de relatório. Para problemas com contas ou permissões, entre em contato com os administradores por e-mail at. For bugs com o código do site ou servidor de hospedagem de problemas , Por favor informe-os em nosso problema tracker. Contribuindo para o desenvolvimento. O código está em github e congratulamo-nos com pull solicitações. Há bilhetes abertos descrevendo bugs existentes e recursos que queremos ou que estão na necessidade de melhoria Ajuda sobre qualquer um destes seria Ser muito apreciado. Existe alguma documentação do desenvolvedor e do usuário no wiki github, incluindo um guia rápido para obter sua própria instância de servidor up. You pode fazer perguntas sobre a lista de discussão cabal-devel ou no IRC no canal hackage no freenode. O novo servidor tem um site automaticamente gerado api Esta é principalmente destinado a documentação para as pessoas que trabalham com o servidor, em vez de como um mapa do site orientado para o usuário, mas pode ser interessante para se E exatamente o que está disponível Isso inclui recursos importantes como o índice legível por máquina de pacotes usados ​​por clientes como cabal-install. Well-Typed e Industrial Haskell Group IHG estão muito satisfeitos em anunciar que o Hackage 2 agora está alimentando o servidor oficial Hackage. Continue lendo para obter uma visão geral dos novos recursos, melhorias no sistema e detalhes sobre como você pode ajudar a tornar o Hackage 2 ainda melhor. Suporte do Industrial Haskell Group. O IHG é um consórcio de empresas que dependem de Haskell. Financiou o esforço para obter Hackage 2 até paridade característica e prepará-lo para a transição O IHG financiou este esforço, porque enquanto o esforço voluntário nos trouxe o primeiro 90 do caminho lá, incluindo a adição de uma série de novos recursos ainda havia os últimos 90 Para fazer para a produção ready. The membros IHG decidiu financiar Hackage 2 não só porque eles são bons cidadãos, mas fora de auto-interesse esclarecido Hackage tem mais de 5000 pacotes escritos por mais de 1000 pessoas Le incluindo os melhores desenvolvedores do mundo Haskell Este é um recurso maciço Os membros IHG reconhecer que as melhorias para as ferramentas e infra-estrutura que a comunidade usa ajuda a comunidade a produzir mais e melhor código Este é um benefício para todos na comunidade, incluindo os usuários comerciais. O IHG está interessado em aumentar a sua filiação para que mais recursos podem ser dedicados a melhorar a plataforma de desenvolvimento Haskell Se a sua organização depende de Haskell de alguma forma, então você pode querer considerar aderir Veja o site IHG para mais detalhes ou contact. Despite o Ajuda do IHG em chegar a este ponto, Hackage é um projeto comunitário, e seu sucesso depende da comunidade manter e melhorar ainda mais o novo servidor O código está agora no github por isso é mais fácil de contribuir, e agora que o servidor está ao vivo Há mais gratificação imediata para voluntários contribuindo correções e novas características. O mais rápido Content Distribution Network. As as necessidades da comunidade inc Hackage contém código escrito de pessoas em todo o mundo, e uptime, bem como a velocidade são primordiais para uma experiência de usuário limpa ao desenvolver . Ofereceu à comunidade um acesso ilimitado ao seu CDN, o que nos permite empurrar TBs de dados através de seus sistemas de borda, fornecer proteção de recursos para servidores e obter análises em tempo real para todos os nossos usuários e data. New features. Though nossa principal prioridade tem sido A paridade de recursos para que possamos trocar de posição, os voluntários contribuíram com vários novos recursos, incluindo uma melhor pesquisa de pacotes, um novo tema do site, uma segurança melhorada, a capacidade de corrigir dependências de pacotes após um release, changelogs e uma interface estilo REST. Nova página de recursos para mais detalhes sobre estes, além de detalhes de outras características que são parcialmente implementadas ou estão em necessidade de improvement. so que estamos fazendo esta atribuição na Uni e eu tenho um desejo grave de fazer a atribuição em haskell Sua simulação de um Mecanismo de negociação de ações A situação é que temos dados provenientes de um csv e queremos analisar cada registro e processá-lo de uma determinada maneira dependente de qual fase de mercado é atribuído a Justificação para a utilização haske É que eu vejo o mecanismo de negociação como o sistema funcional pesado. Eu tive experiência haskell antes, mas apenas uma pequena experiência, nunca nada este big. We estavam querendo executar um thread que iria importar o csvs em uma fila de ordens não processadas e, em seguida, Ter o acesso ao programa principal esta fila para o processamento de cada ordem No entanto, como eu poderia conseguir isso eu sei em C i iria apenas configurar a classe para que ele pudesse acessar a classe CSVParser que iria segurar a fila não processada Isso também significa que o segmento de importação seria Continuamente em execução em todas as fases do mercado ou até que ele terminou de importar o csv file. Any orientação sobre como conseguir isso seria ótimo não olhar para um script totalmente digitado, apenas o que as coisas em haskell i precisaria olhar at. asked Mar 29 12 Em 23 33.closed como não uma pergunta real por Ritch Melton dflemstr Flexo Michael Petrotta Graviton Mar 30 12 em 1 45.É difícil dizer o que está sendo feito aqui Esta questão é ambígua, vaga, incompleta, excessivamente ampla, ou Retórica e não pode ser razoavelmente respondida no seu formulário atual Para ajudar a esclarecer esta questão para que possa ser reaberto, visite o centro de ajuda Se esta pergunta pode ser reformulada para atender as regras no centro de ajuda, edite a questão. Tabela de Conteúdo. Longe, nós temos falado principalmente sobre conceitos de alto nível Haskell também pode ser usado para programação de sistemas de nível inferior É muito possível escrever programas que interface com o sistema operacional em um nível baixo usando Haskell. Neste capítulo, estamos indo Para tentar algo ambicioso uma linguagem Perl-like que é Haskell válido, implementado em puro Haskell, que torna shell scripting fácil Nós vamos implementar tubulação, invocação de comando fácil e algumas ferramentas simples para lidar com tarefas que de outra forma seriam realizadas com grep ou Sed. Specialized módulos existem para diferentes sistemas operacionais Neste capítulo, vamos usar módulos genéricos OS independentes, tanto quanto possível No entanto, vamos estar focando o ambiente POSIX para R O POSIX é um padrão para sistemas operacionais semelhantes a Unix, como Linux, FreeBSD, MacOS X ou Solaris. O Windows não suporta POSIX por padrão, mas o ambiente Cygwin fornece uma camada de compatibilidade POSIX para Windows. Running External Programs. É possível invocar comandos externos a partir de Haskell Para fazer isso, sugerimos usar rawSystem a partir do módulo Isso irá chamar um programa especificado, com os argumentos especificados, e retornar o código de saída desse programa Você pode jogar com ele em ghci. Here, Executamos o equivalente do comando shell ls - l usr rawSystem não analisa os argumentos de uma string ou amplia caracteres curinga 43 Em vez disso, espera que cada argumento seja contido em uma lista Se você não quiser passar nenhum argumento, Uma lista vazia como this. Directory e File Information. The módulo contém algumas funções que podem ser usadas para obter informações do sistema de arquivos Você pode obter uma lista de arquivos em um diretório, renomear ou excluir arquivos, copiar arquivo S, alterar o diretório de trabalho atual ou criar novos diretórios é portátil e funciona em qualquer plataforma onde GHC em si funciona. A biblioteca de referência para fornece uma lista abrangente das funções disponíveis Vamos usar ghci para demonstrar alguns deles A maioria dessas funções São equivalentes diretos para chamadas de biblioteca C ou comandos de shell. Aqui vimos comandos para alterar o diretório de trabalho atual e obter o atual diretório de trabalho do sistema Estes são semelhantes aos comandos cd e pwd no shell POSIX. getDirectoryContents retorna uma lista para cada Item em um determinado diretório Note que em sistemas POSIX, esta lista normalmente inclui os valores especiais e Você normalmente vai querer filtrar estes fora ao processar o conteúdo do diretório, talvez como este. Para obter uma discussão mais detalhada sobre a filtragem dos resultados de getDirectoryContents Consulte o Capítulo 8, Processamento eficiente de arquivos, expressões regulares e correspondência de nome de arquivo. É o filtro notElem, parte confusa Tha T poderia também ser escrito como filtro c - não elem c, Os backticks neste caso efetivamente vamos passar o segundo argumento para notElem ver a seção chamada Infix funções para obter mais informações sobre backticks. You também pode consultar o sistema sobre a localização de Determinados diretórios Esta consulta irá pedir ao sistema operacional subjacente para a informação. Programa Termination. Developers muitas vezes escrevem programas individuais para realizar tarefas específicas Estas peças individuais podem ser combinados para realizar tarefas maiores Um script shell ou outro programa pode executá-los O script de chamada muitas vezes precisa Uma maneira de descobrir se o programa foi capaz de completar a sua tarefa com sucesso Haskell indica automaticamente uma saída sem êxito sempre que um programa é abortado por uma exceção. No entanto, você pode precisar de controle mais fino sobre o código de saída do que talvez você precisa Para retornar códigos diferentes para diferentes tipos de erros O módulo fornece uma maneira de sair do programa e retornar uma saída específica Código de status para o chamador Você pode chamar exitWith ExitSuccess para retornar um código indicando uma terminação bem-sucedida 0 em sistemas POSIX Ou, você pode chamar algo como exitWith ExitFailure 5 que retornará o código 5 para o programa chamador. Dates e Times. Everything de timestamps arquivo Para as transações de negócios envolvem datas e horários Haskell fornece maneiras de manipular datas e horários, bem como recursos para a obtenção de informações de data e hora a partir do system. ClockTime e CalendarTime. In Haskell, o módulo é o principal responsável pela gestão da data e tempo Ele define dois Tipos ClockTime e CalendarTime. ClockTime é a versão Haskell da época POSIX tradicional A ClockTime representa um tempo relativo à meia-noite na manhã de 1 de janeiro de 1970, UTC Um ClockTime negativo representa um número de segundos antes dessa data, enquanto um número positivo representa Uma contagem de segundos depois it. ClockTime é conveniente para computações Como ele rastreia UTC Universal Coordenado UTC, ele doesn T tem que ajustar para fusos horários locais, horário de verão, ou outros casos especiais na manipulação de tempo Cada dia é exatamente 60 60 24 ou 86,400 segundos 44 que faz cálculos de intervalo de tempo simples Você pode, por exemplo, verificar o ClockTime no início de um Longa tarefa, novamente no final, e simplesmente subtrair o tempo de início do tempo de fim para determinar quanto tempo decorrido Você pode então dividir por 3600 e exibir o tempo decorrido como uma contagem de horas, se desejar. ClockTime é ideal para responder a perguntas Tais como estes. Quanto tempo tem decorrido. Qual será o ClockTime 14 dias à frente deste instante preciso. Quando foi o último arquivo modified. What é o momento preciso agora. Estes são bons usos do ClockTime porque eles se referem a precisa, Momentos inequívocos no tempo No entanto, ClockTime não é tão facilmente usado para perguntas como. É ​​hoje segunda-feira. Qual dia da semana será 1 de maio caem no próximo ano. Qual é o horário atual no meu fuso horário local, tendo a presença potencial de Daylight Economizando tempo DST em conta. CalendarTime armazena um tempo da maneira que os humanos fazem com um ano, mês, dia, hora, minuto, segundo, fuso horário e informações de horário de verão É fácil de converter isso em uma seqüência convenientemente exibível, ou para responder a perguntas sobre o Hora local. Você pode converter entre ClockTime e CalendarTime em Haskell irá incluir funções para converter um ClockTime para um CalendarTime no fuso horário local, ou para um CalendarTime representando UTC. Using ClockTime. ClockTime é definido em como this. O primeiro Integer representa o número De segundos desde a época O segundo Inteiro representa um número adicional de picossegundos Porque ClockTime em Haskell usa o tipo Integer ilimitado, ele pode efetivamente representar um intervalo de datas limitado apenas por recursos computacionais. Vamos olhar algumas maneiras de usar ClockTime Primeiro, há A função getClockTime que retorna a hora atual de acordo com o relógio do sistema s. Se você esperar um segundo e executar getClockTime novamente, você vai vê-lo retornando um tempo atualizado N Otice que a saída deste comando era uma corda agradável-olhando, completo com informação do dia-de-semana Isso é devido à instância de Show para ClockTime Vamos olhar para o ClockTime em um nível mais baixo. Aqui nós primeiro construímos um ClockTime que representa o Ponto no tempo 1000 segundos após a meia-noite em 1 de janeiro de 1970, UTC Esse momento no tempo é conhecido como a época Dependendo do seu fuso horário, este momento pode corresponder à noite de 31 de dezembro de 1969, em seu fuso horário local. O segundo Exemplo mostra-nos puxando o número de segundos para fora do valor retornado por getClockTime Agora podemos manipulá-lo, como assim. Isso irá mostrar qual será o tempo exatamente 24 horas a partir de agora em seu fuso horário local, uma vez que há 86.400 segundos em 24 horas. Use CalendarTime. As seu nome implica, CalendarTime representa o tempo como nós em um calendário Tem campos para informações como ano, mês e dia CalendarTime e seus tipos associados são definidos como this. There são algumas coisas sobre estes st As ructures que devem ser destacadas. ctWDay ctYDay e ctTZName são geradas pelas funções de biblioteca que criam um CalendarTime, mas não são usadas nos cálculos Se você estiver criando um CalendarTime manualmente, não é necessário colocar valores precisos nesses campos, a menos que o seu posterior Os cálculos dependerão deles. Todos estes três tipos são membros da Eq Ord Read e Show typeclasses Além disso, Month e Day são declarados como membros do Enum e Bounded typeclasses Para mais informações sobre estes typeclasses, consulte a seção chamada Importante Built-In Typeclasses. You pode gerar valores CalendarTime várias maneiras que você poderia começar por converter um ClockTime para um CalendarTime como this. We usado getClockTime para obter o atual ClockTime do relógio do sistema Next, toCalendarTime converte o ClockTime para um CalendarTime que representa o Time no fuso horário local toUTCtime executa uma conversão semelhante, mas seu resultado está no fuso horário UTC em vez do timezon local E. Notice que toCalendarTime é uma função IO, mas toUTCTime não é A razão é que toCalendarTime retorna um resultado diferente, dependendo do fuso horário configurado localmente, mas toUTCTime retornará o mesmo resultado exato sempre que for passado a mesma fonte ClockTime. It s Fácil de modificar um valor de CalendarTime. Em este exemplo, primeiro tomou o valor de CalendarTime de mais cedo e simplesmente mudou seu ano para 1960 Então, usamos toClockTime para converter o valor não modificado para um ClockTime e, em seguida, o valor modificado, para que você possa ver o Diferença Observe que o valor modificado mostra um número negativo de segundos depois convertido em ClockTime Isso é esperado, uma vez que um ClockTime é um deslocamento de meia-noite em 1 de janeiro de 1970, UTC, e este valor está em 1960. Você também pode criar CalendarTime Note que mesmo que 15 de janeiro de 2010, isn ta domingo - e isn t dia 0 no ano - o sistema foi capaz de processar isso apenas multa De fato, se converter o valor para um ClockTime e Então de volta a um CalendarTime você encontrará esses campos devidamente preenchidos in. TimeDiff para ClockTime. Because pode ser difícil de gerenciar as diferenças entre ClockTime valores de uma forma humana-friendly, o módulo inclui um TimeDiff tipo TimeDiff pode ser usado, onde conveniente, Para lidar com essas diferenças É definido como this. Functions such as diffClockTimes e addToClockTime ter um ClockTime e um TimeDiff e lidar com os cálculos internamente convertendo para um CalendarTime em UTC, aplicando as diferenças e convertendo de volta para um ClockTime. Let s ver como Ele funciona. Começamos por gerar um ClockTime representando meia-noite 5 de fevereiro de 2008 em UTC Observe que, a menos que seu fuso horário é o mesmo que UTC, quando este tempo é impresso na tela, ele pode aparecer na noite de 4 de fevereiro porque Ele é formatado para seu timezone local. Em seguida, nós adicionamos um mês a ele chamando addToClockTime 2008 é um ano bissexto, mas o sistema segurou que corretamente e nós começamos um resultado que tenha o mesmo dat E e tempo em março Usando toUTCTime podemos ver o efeito sobre isso no timezone UTC original. Para uma segunda experiência, criamos um tempo representando a meia-noite em 30 de janeiro de 2009 em UTC 2009 não é um ano bissexto, então podemos Pergunto o que vai acontecer ao tentar adicionar um mês para ele Podemos ver que, uma vez que nem 29 de fevereiro ou 30 existem em 2009, acabamos com março 2.Finalmente, podemos ver como diffClockTimes transforma dois valores ClockTime em um TimeDiff embora apenas Os segundos e picossegundos são preenchidos A função normalizeTimeDiff leva tal TimeDiff e reformata-lo como um ser humano pode esperar para vê-lo. File Modificação Times. Many programas precisam descobrir quando determinados arquivos foram modificados pela última vez Programas como ls ou gerenciadores de arquivos gráficos Normalmente exibem o tempo de modificação de arquivos O módulo contém uma função de getModificationTime de plataforma cruzada Demora um nome de arquivo e retorna um ClockTime representando a hora em que o arquivo foi modificado pela última vez Por instância. POSIX plataformas maintai N não apenas um tempo de modificação conhecido como mtime, mas também o tempo de último acesso de leitura ou gravação atime ea hora da última mudança de status ctime Uma vez que esta informação é específica de POSIX, o módulo multi-plataforma não fornece acesso a ele Em vez disso, Você precisará usar funções em Aqui está uma função de exemplo para fazer that. Notice que chamar para getFileStatus Essa chamada mapeia diretamente para a função C stat Seu valor de retorno armazena uma grande variedade de informações, incluindo tipo de arquivo, permissões, proprietário, grupo, E os três valores de tempo que estamos interessados ​​em fornece várias funções, como accessTime que extraem as informações que estamos interessados ​​fora do opacos FileStatus tipo retornado por getFileStatus. As funções como accessTime retornar dados em um tipo POSIX específico chamado EpochTime que se Converter para um ClockTime usando a função toct também fornece uma função setFileTimes para definir o atime e mtime para um arquivo 45.Extended Exemplo Piping. We ve apenas visto como invocar programa externo S Às vezes, precisamos de mais controle que isso Talvez precisamos obter a saída desses programas, fornecer entrada, ou até mesmo juntar vários programas externos Piping pode ajudar com todas essas necessidades Piping é muitas vezes usado em shell scripts Quando você configurar um tubo No shell, você executa vários programas A saída do primeiro programa é enviado para a entrada do segundo Sua saída é enviada para o terceiro como entrada, e assim por diante A saída do último programa s normalmente vai para o terminal, ou poderia ir Para um arquivo Aqui é uma sessão de exemplo com o shell POSIX para ilustrar o comando piping. This executa três programas, os dados de tubulação entre eles Ele começa com ls etc que gera uma lista de todos os arquivos ou diretórios em etc A saída de ls é enviado como entrada Para grep Demos grep uma expressão regular que fará com que a saída apenas as linhas que começam com m e, em seguida, conter ap em algum lugar na linha Finalmente, o resultado disso é enviado para tr Demos tr opções para converter tudo para maiúsculas A saída De tr isn t definir em qualquer lugar em particular, por isso é exibido na tela. Em tal situação, o shell lida com a criação de todos os pipelines entre os programas Usando algumas das ferramentas POSIX em Haskell, podemos realizar a mesma coisa. Antes de descrever Como fazer isso, devemos primeiro avisá-lo que os módulos expor uma interface de muito baixo nível para sistemas Unix As interfaces podem ser complexas e suas interações podem ser complexas, bem, independentemente da linguagem de programação que você usa para acessá-los A natureza total Dessas interfaces de baixo nível tem sido o tópico de livros inteiros em si, então neste capítulo vamos apenas arranhar a superfície. Usando Pipes para Redirection. POSIX define uma função que cria um pipe Esta função retorna dois descritores de arquivos FDs, que são semelhantes No conceito a uma Haskell Handle Um FD é a extremidade de leitura do tubo, eo outro é o fim de escrita Qualquer coisa que é escrito para o fim de escrita pode ser lido pela extremidade de leitura Os dados são empurrados através de um tubo em H Askell, você chama createPipe para acessar esta interface. Having um pipe é o primeiro passo para ser capaz de canalizar dados entre programas externos Também devemos ser capazes de redirecionar a saída de um programa para um pipe ea entrada de outro programa de um Pipe A função Haskell dupTo realiza isto Faz exame de um FD e faz uma cópia dele em um outro número de FD POSIX FDs para a entrada padrão, a saída padrão, eo erro padrão têm os números FD predefinidos de 0, 1, e 2, respectivamente Renumerando um Ponto final de um tubo para um desses números, podemos efetivamente causar programas para ter sua entrada ou saída redirecionada. Há outra peça do quebra-cabeça, no entanto, podemos t apenas usar dupTo antes de uma chamada, como rawSystem porque isso iria bagunçar o Padrão de entrada ou saída do nosso processo Haskell principal Além disso, rawSystem bloqueia até que o programa invocado executa, deixando-nos nenhuma maneira de iniciar vários processos em execução em paralelo Para fazer isso acontecer, devemos usar forkProcess Este é um muito especial Função Ele realmente faz uma cópia do programa em execução no momento e você acabar com duas cópias do programa em execução ao mesmo tempo Haskell s função forkProcess tem uma função para executar no novo processo conhecido como a criança Temos essa chamada de função dupTo Depois de ter feito isso, ele chama executeFile para realmente invocar o comando Esta é também uma função especial se tudo correr bem, nunca retorna Isso é porque executeFile substitui o processo em execução com um programa diferente Eventualmente, o processo Haskell original chamará getProcessStatus para Espere que os processos filhos terminem e aprendam seus códigos de saída. Sempre que você executa um comando em sistemas POSIX, se você acabou de digitar ls na linha de comando ou usou rawSystem em Haskell, sob a capa, forkProcess executeFile e getProcessStatus ou seus C Equivalentes estão sempre sendo usados ​​Para configurar tubos, estamos duplicando o processo que o sistema usa para iniciar programas, e adicionando algumas etapas envolvendo tubulação e Redirecionamento ao longo do way. There são algumas outras coisas de limpeza que devemos ter cuidado sobre Quando você chamar forkProcess quase tudo sobre o seu programa é clonado 46 Isso inclui o conjunto de descritores de arquivo aberto alças Programas detectar quando eles são feitos recebendo entrada de um tubo Verificando o indicador de fim de arquivo Quando o processo na extremidade de escrita de um pipe fecha o pipe, o processo no final de leitura receberá uma indicação de fim de arquivo No entanto, se o descritor de arquivo de escrita existir em mais de um Processo, o indicador de fim de arquivo não será enviado até que todos os processos tenham fechado que FD particular. Portanto, devemos manter o controle de quais FDs são abertos para que possamos fechá-los todos nos processos filho Também devemos fechar as extremidades da criança Os tubos no processo pai logo que possible. Here é uma implementação inicial de um sistema de tubulação em Haskell. Let s experimentar com isso em ghci um pouco antes de olhar para como ele works. We começar por executar um simples comando, pwd wh Ich apenas imprime o nome do diretório de trabalho atual Passamos para a lista de argumentos, porque pwd não precisa de quaisquer argumentos Devido aos typeclasses utilizados, Haskell não pode inferir o tipo de por isso especificamente mencionar que é uma String. Then nós começ Em comandos mais complexos Eu funciono o ls que envia isto através de grep No fim, eu estabeleci um tubo para funcionar o exato o mesmo comando que eu funcionei através de um tubo construído shell-no começo desta seção É ainda não tão agradável quanto era No shell, mas, em seguida, novamente o nosso programa ainda é relativamente simples quando comparado com o shell. Let s olhar para o programa A primeira linha tem uma cláusula especial OPTIONSGHC Isso é o mesmo que passar - fglasgow-exts para ghc ou ghci Estamos Usando uma extensão GHC que nos permite usar um String, String tipo como uma instância de um typeclass 47 Ao colocá-lo no arquivo de origem, não temos que lembrar de especificá-lo cada vez que usamos este módulo. Após as linhas de importação, Nós definimos alguns tipos Primeiro, nós definimos o tipo SysCommand String, S Tring como um alias Este é o tipo que um comando a ser executado pelo sistema tomará Nós usamos dados desse tipo para cada comando na execução de exemplo acima O tipo CommandResult representa o resultado da execução de um dado comando eo tipo CloseFDs representa o Lista de FDs que nós devemos fechar em cima de forking um processo novo da criança. Em seguida, nós definimos uma classe nomeada CommandLike Esta classe será usada para funcionar coisas, onde uma coisa pôde ser um programa autônomo, um tubo setup entre dois ou mais programas, Ou no futuro, até funções Haskell puras Para ser um membro desta classe, apenas uma função - invocar - precisa estar presente para um determinado tipo Isso nos permitirá usar runIO para iniciar um comando autônomo ou um pipeline Também pode ser útil para definir um pipeline, uma vez que podemos ter uma pilha de comandos em um ou ambos os lados de um determinado comando. Nossa infra-estrutura de tubulação vai usar strings como a maneira de enviar dados de um processo para outro Podemos tirar proveito De Haskell Suporte para leitura preguiçosa via hGetContents enquanto lê dados e usa forkIO para permitir que a escrita ocorra em segundo plano Isso funcionará bem, embora não tão rápido como conectar os pontos de extremidade de dois processos diretamente juntos 48 Faz a implementação bastante simples, Cuidado em não fazer nada que exigiria que toda a Cadeia fosse armazenada em buffer, e deixe a preguiça de Haskell fazer o resto. Em seguida, definimos uma instância de CommandLike para SysCommand Criamos dois pipes um para usar para a entrada padrão do novo processo s Outro para sua saída padrão Isso cria quatro pontos de extremidade e, portanto, quatro descritores de arquivo Nós adicionamos os descritores de arquivo pai para a lista daqueles que devem ser fechados em todas as crianças Estes seriam o fim de gravação da entrada padrão da criança e o fim de leitura Da saída padrão da criança Em seguida, nós fork o processo filho No pai, podemos então fechar os descritores de arquivo que correspondem à criança Podemos t fazer isso antes do garfo, porque então eles wouldn t Estar disponível para a criança Nós obter um identificador para o descritor de arquivo stdinwrite, e iniciar um thread via forkIO para gravar os dados de entrada para ele Nós, então, definir waitfunc que é a ação que o chamador irá invocar quando ele está pronto para esperar o chamado Processo para terminar Enquanto isso, a criança usa dupTo fecha os descritores de arquivo que não precisa, e executa o comando. Em seguida, definimos algumas funções de utilitário para gerenciar a lista de descritores de arquivo Depois disso, definimos as ferramentas que ajudam a configurar pipelines First , Nós definimos um novo tipo PipeCommand que tem uma fonte e destino Tanto a fonte como o destino devem ser membros de CommandLike Também definimos o operador de conveniência - Então, fazemos PipeCommand uma instância de CommandLike Sua implementação de invoke inicia o primeiro comando com o dado , Obtém sua saída e passa essa saída para a invocação do segundo comando. Em seguida, retorna a saída do segundo comando e faz com que a função getExitStatus espere Para e verificar os status de saída de ambos os comandos. Terminamos definindo runIO Esta função estabelece a lista de FDs que devem ser fechados no cliente, inicia o comando, exibe sua saída e verifica seu estado de saída. Better Piping.

No comments:

Post a Comment