мл тип данных (с примитивными функциями), как сделать? - PullRequest
0 голосов
/ 01 июня 2011

У меня есть этот тип данных

datatype e = X | Const of int | P of e*e | S of e*e | M of e*e | D of e*e;

и эта процедура

val rec evl = fn (Const k)=>(fn x=>k)| X=> (fn x=>x)| P(e1,e2)=> (fn x=> (evl e1 x)+(evl e2 x))| S(e1,e2)=> (fn x=> (evl e1 x)-(evl e2 x))| M(e1,e2)=> (fn x=> (evl e1 x)*(evl e2 x))| D(e1,e2)=> (fn x=> (evl e1 x)/(evl e2 x));

как развернуть этот тип данных и процедуру evl, чтобы сделать:

-valaddub = evl (A (X (1), X (2), X (3), S (X (4), X (5))));addub (4,5,2,9,8) вернуть его = 12 (4 + 5 + 2 + (9-8))

P = +, S = -, M= *, D = / и не только для X (5), мне нужно для X (n) ...?

1 Ответ

0 голосов
/ 01 июня 2011

Некоторые примечания о вашем типе данных и функции:

  • X - избыточный случай, он не имеет значение в контексте арифметики выражение.
  • Вы злоупотребили функциями лямда, это делает ваш код так трудно понимать.

S (вычитание) и D (деление) не являются коммутативными, поэтому делать эти операции над списком аргументов - плохая идея. Я демонстрирую, как это сделать с помощью P (плюс) и M (умножение):

datatype e2 = Const of int | P of e2 list | M of e2 list;
val rec evl2 =
         fn Const k => k    
         | P es => List.foldl (fn (e, acc) => acc + (evl2 e)) 0 es
         | M es => List.foldl (fn (e, acc) => acc * (evl2 e)) 1 es;

Например: evl2 (P [Const 3, Const 2, M [Const 3, Const 2, Const 1]]) вернет 11.

Если вы все еще хотите сделать это с S и D, вы можете сделать вывод из приведенного выше фрагмента кода.

...