Em uma linguagem pura como Haskell, todos os dados são imutáveis e nenhuma estrutura de dados existente pode ser alterada de forma alguma
Na verdade, isso geralmente não é verdade. Linguagens puras usam avaliação não estrita (preguiçosa) para que a avaliação de potencialmente todas as subexpressões seja adiada. Expressões não avaliadas geralmente são alocadas em heap como um "thunk". Quando necessário, a expressão é avaliada e a conversão é alterada para o valor resultante.
Quais estratégias e técnicas os coletores de lixo empregam em face da pureza que eles não usariam de outra maneira?
A única coisa em que consigo pensar é nos buracos negros . Não me lembro de ter visto mais nada do lado do GC nos trabalhos de pesquisa de Haskell.
O que funciona muito bem no GC de uma linguagem impura que não funciona em um contexto puro?
A barreira de gravação do GC. Linguagens impuras tendem a escrever ponteiros muito mais no heap, e tendem a ter suas barreiras de gravação mais fortemente otimizadas.
Outros algoritmos de GC, como região de marca, são muito mais viáveis no contexto de linguagens impuras porque podem ter taxas de alocação muito mais baixas do que linguagens puras.
Que outros novos problemas os idiomas puros criam para os GCs?
Linguagens puras são muito raras; portanto, há muito menos dados sobre como os programas puros usam a memória e, portanto, você está começando em uma posição pior ao tentar escrever um GC para uma linguagem pura.