Pergunta

Eu escrevi uma função em haskell que usa alguns parâmetros como Word32, String (ignorar currying) e gera IO Word32.Agora, este é um função no verdadeiro sentido: para as mesmas entradas, a saída será sempre a mesma.Não tem efeitos colaterais.A razão pela qual a função retorna IO Word32 em vez de Word32 é que a função atualiza muitos registradores de deslocamento de feedback linear de 32 bits (lfsr) e outros registradores várias vezes em um loop para calcular a saída final do Word32.

Minha pergunta é esta:Dado que esta função efetivamente não tem efeitos colaterais, é possível ocultar essas atualizações de registro dentro da implementação da função para que a função retorne Word32 e não IO Word32?Se sim, como?

Foi útil?

Solução

Sim!Haskell pode fazer isso.

A mônada ST

Se você realmente usa estados mutáveis ​​(registros), que estão totalmente ocultos do observador fora da função, então você está em a mônada ST, uma mônada apenas para efeitos de memória.Você entra no mundo ST via runST, e quando você sai da função, é garantido que todos os efeitos não estarão visíveis.

É precisamente o ambiente computacional certo para trabalhar com estado local e mutável.

Estado puramente funcional:a mônada do Estado

Se, no entanto, você não estiver realmente alterando registros ou células, mas sim atualizando um valor puramente funcional muitas vezes, um ambiente mais simples estará disponível: a mônada do Estado.Isto não permite estado mutável, mas dá uma ilusão de estado local.

IO e inseguroPerformIO

Finalmente, se você tiver efeitos locais e mutáveis, como no ST mônada, mas por algum motivo ou outro, você precisará de operações IO nesse estado (como por meio de uma chamada FFI), poderá simular o ST mônada, com quase a mesma segurança, usando unsafePerformIO, em vez de runST, para introduzir um ambiente IO local.Como a mônada IO não possui tipos legais para impor a abstração, você precisará garantir manualmente que os efeitos colaterais não serão observáveis.

Outras dicas

Se você importou essa função usando o FFI, basta remover o IO do tipo de retorno.Caso contrário, use unsafePerformIO :: IO a -> a de System.IO.Unsafe.Observe que esta função é uma das funções mais perigosas em Haskell.Não o use se não tiver certeza das consequências.Mas para o seu propósito, parece bom.

Sim, este seria um uso legítimo de insensível. Mas é só ok se você tem certeza de que não há efeitos visíveis.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top