Pergunta

Uma pessoa no Reddit trouxe este código a minha atenção:

main = do
  let ns = [print 1, print 2, print 3]
  sequence_ ns
  sequence_ $ reverse ns
  sequence_ $ tail ns ++ [head ns]
  head ns

O que está acontecendo aqui, é que nós temos uma matriz de operações que podemos fazer coisas, como reverter ou obter a sua cauda ou a cabeça.

Impressionante.

O que eu quero é chegar em elementos individuais e alterá-las para o bem.Por exemplo, eu quero ser capaz de fazer algo como isto:

ns !! 0

e obter algo como [print, 1] e, em seguida, altere o último elemento, digamos, 3.14, de modo a que a função de impressão 3.14.

É possível, no Haskell, ou devo apenas voltar para o LISP?

UMA IMPORTANTE EDIÇÃO:Eu meio que errou.Eu entendo que eu preciso para criar uma nova lista.É possível obter os argumentos de uma função, que é uma parte de uma lista?O que eu quero é a capacidade de compor funções de seus identificadores/argumentos e também ser capaz de quebrar uma função de identificador/argumento antes que ele seja avaliado.

Foi útil?

Solução

É um pouco mais complicado do que em Lisp, mas para metaprogramação em Haskell, você pode usar Modelo Haskell.

Por exemplo, [|print 1|] será traduzido para

return $ AppE (VarE $ mkName "print") (LitE $ IntegerL 1)

que tem o tipo Q Exp (uma citação de uma expressão).

Se você deseja conspirar seus próprios dados em uma cotação, [|print $(foo 3.14)|] será executado foo 3.14 em tempo de compilação.

Outras dicas

Depois de aplicar um valor a uma função, não há como recuperá -lo. Tente envolver a função e seu argumento em um tipo de dados que você pode avaliar ou decompor, dependendo de suas necessidades.

data App a b = App (a -> b) a
runApp (App a b) = a b
ns = [App print 1, App print 2, App print 3]
main = do
    sequence_ $ map runApp ns
    let ns2 = [App fun (arg^2) | App fun arg <- ns]
    sequence_ $ map runApp ns2

Saídas

1
2
3
1
4
9

Você quer transformar a lista?Você deve voltar para lisp ;-)

Os valores são imutáveis em Haskell.O Haskell-forma é criar uma nova lista, que é equivalente à lista de idade, exceto para o último elemento.

(Existem alguns truques envolvendo mônadas, onde você pode simular valores mutáveis e os ponteiros, mas que provavelmente não é o que você quer aqui.)

EDITAR:Não totalmente certo, eu entendo o editado pergunta, mas você pode lidar com função e argumento separadamente, como dados e, em seguida, "aplicar" e, mais tarde, por exemplo.;

do
    let ns = [(print, 1), (print, 2), (print, 3)]
    sequence_ $ map (\(f,a)->f a) ns

Como já foi dito o asclock, uma maneira é criar uma nova lista, mas você pode ter mutável matrizes dentro do IO mônada com IOArray se você realmente quer

import Data.Array.IO

seqArr_ arr = getElems arr>>=sequence_

main= do
  arr <- newListArray (0,2) [print 1,print 2,print 3] :: IO (IOArray Int (IO ()))
  seqArr_ arr  -- prints 1 2 3
  writeArray arr 2 (print 3.14) -- change the last element
  seqArr_ arr  -- prints 1 2 3.14
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top