efeitos extensíveis em purescript

5

Em Purescript , IO e outros efeitos são gerenciados com os efeitos Eff monad e extensible, que são declarados assim:

main :: Eff (trace :: Trace, random :: Random) {}

Então, se eu entendi bem, essa declaração main só permite registrar no console e gerar números aleatórios. O trace :: Trace, random :: Random é uma linha de efeito, ou seja, uma coleção de efeitos rotulados não ordenados.

Agora obtenho que Trace é um efeito e trace é seu rótulo. Mas por que precisamos dos dois? Faz sentido para registros como { foo::String, bar::String } , mas não consigo entender por que precisaria gerenciar dois efeitos de Random com rótulos diferentes. ou seja, eu escreveria o seguinte:

main :: Eff (Trace, Random) {} -- no redundant labels

Os rótulos de efeito são úteis em purescript? Se sim para quê?

    
por Simon 30.06.2014 / 10:00
fonte

2 respostas

6

A resposta simples é que o maquinário para linhas já existia no typechecker, desde o primeiro lançamento do compilador PureScript, então fazia sentido reutilizá-lo para definir o Eff monad. A única mudança foi permitir que as linhas fossem parametrizadas pelo tipo de tipos indexados por seus rótulos.

Certamente parece que rótulos são desnecessários, e seriam, se os efeitos fossem apenas símbolos. Outra resposta, no entanto, é que os rótulos nos permitem manter a propriedade desejável de ter os mais completos unificadores no sistema de tipos.

Exemplo Contrivado

Suponha que você definiu um manipulador cujo tipo continha uma linha de efeitos com duas ou mais variáveis de tipo desconhecido:

runFooBarEffects :: forall eff foo bar. Eff (foo :: foo, bar :: bar | eff) a -> Eff (combined :: Baz foo bar | eff) a

E uma ação correspondente com tipos de efeitos concretos:

myAction :: Eff (foo :: Foo, bar :: Bar, trace :: Trace) String

Quando tentamos executar essa ação com runFooBarEffects myAction , o typechecker infere corretamente o tipo de resultado Eff (combined :: Baz Foo Bar, trace :: Trace) String pela unificação.

No entanto, imagine se não houvesse rótulos presentes. O algoritmo de unificação não poderá continuar, porque foo pode ser unificado com Foo ou Bar , pois as linhas não são ordenadas. Não há mais um unificador mais geral para as duas linhas.

Este exemplo é de fato inventado, mas ilustra o fato de que, como não estamos restritos a simples tipos atômicos (símbolos) aparecendo em linhas, mas em vez disso, temos uma rede inteira de tipos, precisamos de rótulos para manter o tipo sane system. / p>     

por 01.07.2014 / 03:17
fonte
2

Eu nunca usei o PureScript, mas a resposta curta é sim, os rótulos de efeito são úteis para a modelagem efeitos de uma forma baseada em princípios.

Não sei qual é o seu histórico, por isso não sei em que nível responder à pergunta. Você está familiarizado com os efeitos colaterais, as desvantagens de seu uso irrestrito, programação funcional e por que tentamos evitar efeitos colaterais em FP? Em caso afirmativo, isso fornece uma boa motivação para os sistemas de efeitos, que tornam possível usar efeitos sem permitir seu uso irrestrito; em linguagens com tipagem estática, é até possível rastrear explicitamente os efeitos no sistema de tipos. Um sistema de efeitos populares é o monad transformers (claro que eles são não sem inconvenientes - mas eles têm implementado em idiomas populares e, portanto, são fáceis de começar a experimentar com).

Se você entende tudo isso, então talvez sua pergunta seja simplesmente por que alguém precisaria / desejaria várias instâncias separadas do mesmo efeito? Geradores de números pseudo-aleatórios não geram números aleatórios, e os relacionamentos entre os números gerados não são aleatórios - então, com dois (ou mais) efeitos aleatórios separados, você pode essencialmente ter dois (ou mais) números pseudo aleatórios não correlacionados fluxos.

Aviso: Eu nunca usei o PureScript - esta é apenas a minha opinião!

Por que alguém precisaria / desejaria várias instâncias separadas do mesmo efeito? Geradores de números pseudo-aleatórios não geram números aleatórios, e os relacionamentos entre os números gerados não são aleatórios - então, com dois (ou mais) efeitos aleatórios separados, você pode essencialmente ter dois (ou mais) números pseudo aleatórios não correlacionados fluxos.

Outro benefício de usar nomes - mesmo quando não há mais do que uma única instância de qualquer efeito dado - é que algum significado semântico pode ser anexado aos efeitos através de um rótulo significativo. Em outras palavras, nem todos os State s são criados iguais!

Outro exemplo de uso de múltiplas instâncias do mesmo efeito, verifique os combinadores do analisador. Estes são fáceis de construir a partir de sistemas de efeitos, como transformadores monad. Um simples analisador de backtracking e relatório de erros pode ser construído a partir de:

  • Estado - trata a string de entrada
  • Erro - relatório de erros
  • Talvez - retrocedendo

efeitos (desculpe, essa é a terminologia do Haskell - não sei como eles mapeiam os efeitos do PureScript). Se você quisesse também rastrear a posição (linha, coluna) durante a análise, você poderia adicionar um segundo efeito de estado. Você também pode rastrear declarações de variáveis globais usando um efeito de terceiro estado (supondo que esteja analisando uma linguagem de programação). Embora, em princípio, você pudesse combinar todos os três efeitos de Estado em um único, isso introduziria o acoplamento e seria menos extensível; tê-los separados evita esse acoplamento.

    
por 30.06.2014 / 22:11
fonte