Оставляя значения для опций в Mathematica без оценки - PullRequest
4 голосов
/ 18 февраля 2011

У меня проблемы с написанием функции, которая принимает параметры.Одним из значений параметра является функция.Я один, чтобы получить на это значение, но держать его недооцененным.Я перепробовал все, что мог придумать, но пока ничего не получалось.

В основном, чтобы проиллюстрировать это, я попытался:

SetAttributes[Foo, HoldRest];
Options[Foo] = {Blah -> None}

Foo[x_, OptionsPattern[]] :=
    Module[{blah},

        blah = OptionValue[Automatic, Automatic, Blah, Hold];
        .
        .
        .

Затем, когда у меня есть:

func[a_, b_, c_] := a + b + c;

Я бы хотел позвонить в Foo:

Foo[2, Blah -> func[1, 2, 3]]

И нужно, чтобы переменная "blah" (внутри Foo) была недооценена, т.е. blah = func [1, 2, 3].

Заранее благодарю за помощь!

Редактировать:

По причинам, которые слишком длинны для разработки, я не могу использовать RuleDelayed (:>).Я пытаюсь написать функцию, которая будет в пакете, которая будет использоваться другими людьми, которые на самом деле не знают Mathematica, поэтому они понятия не имеют, что:> is.Использование правил (->) для задания опций и их значений является стандартным способом, и они знакомы с этим.

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

Options[GenerateNumbers] = {GeneratorFunction -> None};

GenerateNumbers[n_, OptionsPattern[]] :=
    Module[{func},

        func = OptionValue[GeneratorFunction];
        Table[func, {n}]
    ]     
]

Теперь, если бы я вызвал эту функцию со значениями следующим образом:

GenerateNumbers[5, GeneratorFunction -> RandomReal[10]]

Он бы возвратил список из 5 чисел, которыеодинаковы, поскольку RandomReal [10] вычисляется один раз, а не на каждой итерации таблицы.Я хочу предотвратить это.Проблема более сложная, но она такова.

Спасибо!

Ответы [ 3 ]

5 голосов
/ 18 февраля 2011

Используйте имя для OptionsPattern, а затем оберните захваченный объект последовательности с List и Unevaluated. Минимальный способ захвата правой части для Blah:

SetAttributes[Foo, HoldRest]; Options[Foo] = {Blah -> None};
Foo[x_, opts : OptionsPattern[]] :=
 Module[{blah},
  blah = OptionValue[Foo, Unevaluated[{opts}], Blah, Hold];
  blah]

Тестирование:

In[2]:= Foo[x, Blah -> (1 + 1)]
Out[2]= Hold[1 + 1]
4 голосов
/ 18 февраля 2011

Почему бы вам не использовать RuleDelayed?

Foo[2, Blah :> func[1, 2, 3]]

В этом случае blah=Hold[func[1, 2, 3]], как и ожидалось.

3 голосов
/ 18 февраля 2011

Ваше использование опций немного странно.Если вы хотите передать какое-либо выражение, заключенное в Hold, почему бы не перенести его в Hold при прохождении, например Blah->Hold[func[1,2,3]]?В любом случае, принимая это простое определение для Foo:

Foo[x_, OptionsPattern[]] :=
Module[{blah},
   blah = OptionValue[Automatic, Automatic, Blah, Hold];
   blah
],

, вы можете выполнить то, что вы хотите, передав параметр с RuleDelayed вместо Rule:

In[7]:= func[a_, b_, c_] := a + b + c;

In[8]:= Foo[2, Blah :> func[1, 2, 3]]

Out[8]= Hold[func[1, 2, 3]] 

HTH

Редактировать:

Если вы не хотите, чтобы Hold оборачивался, вот один из способов избавиться от него:

In[25]:= 
ClearAll[setDelayedHeld];
SetAttributes[setDelayedHeld, HoldFirst];
setDelayedHeld[lhs_, Hold[rhs_]] := lhs := rhs

In[28]:= 
Clear[Foo];
Foo[x_, OptionsPattern[]] :=
 Module[{blah},
   setDelayedHeld[blah, OptionValue[Automatic, Automatic, Blah, Hold]];
   OwnValues[blah]]

In[30]:= Foo[2, Blah :> func[1, 2, 3]]

Out[30]= {HoldPattern[blah$1018] :> func[1, 2, 3]}

Я возвращаю OwnValuesдля blah, чтобы показать, что ему было присвоено func[1,2,3] без оценки последнего - если это то, что вы хотите.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...