(эмулированные) макросы в Haskell?

Поскольку для... в перечисляет через объект, который содержит массив, не сам массив. Если я добавляю функцию к опытной цепочке массивов, которая будет также включена. Т.е.

Array.prototype.myOwnFunction = function() { alert(this); }
a = new Array();
a[0] = 'foo';
a[1] = 'bar';
for(x in a){
 document.write(x + ' = ' + a[x]);
}

Это запишет:

0 = foo
1 = bar
myOwnFunction = function() { alert(this); }

И так как Вы никогда не можете быть уверены, что ничто не будет добавлено к опытной цепочке просто, используют, чтобы цикл перечислил массив:

for(i=0,x=a.length;i<x;i++){
 document.write(i + ' = ' + a[i]);
}

Это запишет:

0 = foo
1 = bar
16
задан mannicken 18 August 2009 в 20:05
поделиться

4 ответа

Это немного сложнее, чем в Lisp, но для метапрограммирования в Haskell вы можете использовать Template Haskell .

Например, , [| print 1 |] будет преобразован в

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

, который имеет тип Q Exp (цитата выражения).

Если вы хотите склеить свое собственное данные в цитату, [| print $ (foo 3.14) |] выполнит foo 3.14 во время компиляции.

11
ответ дан 30 November 2019 в 21:19
поделиться

После того, как вы применили значение к функции, нет возможности чтобы вернуть его. Попробуйте заключить функцию и ее аргумент в тип данных, который вы можете оценить или разложить в зависимости от ваших потребностей.

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

Выходы

1
2
3
1
4
9
11
ответ дан 30 November 2019 в 21:19
поделиться

Вы хотите изменить список? Вам следует вернуться к lisp; -)

Значения неизменны в Haskell. Способ Haskell заключается в создании нового списка, который эквивалентен старому списку, за исключением последнего элемента.

(Есть несколько уловок с использованием монад, с помощью которых вы можете имитировать изменяемые значения и указатели, но это, вероятно, не то, что вам здесь нужно.)

РЕДАКТИРОВАТЬ: Не совсем уверен, что я понимаю отредактированный вопрос, но вы можете обрабатывать функции и аргумент отдельно как данные, а затем "применить" позже, например;

do
    let ns = [(print, 1), (print, 2), (print, 3)]
    sequence_ $ map (\(f,a)->f a) ns
4
ответ дан 30 November 2019 в 21:19
поделиться

Как уже говорилось, способ haskell - это просто создать новый список, но вы можете иметь изменяемые массивы внутри монады ввода-вывода с помощью IOArray, если вы действительно хотите

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
1
ответ дан 30 November 2019 в 21:19
поделиться
Другие вопросы по тегам:

Похожие вопросы: