Таким образом, для каждого из трех операций, вы, кажется, определили вспомогательные функции, которые выполняют логику операций. Что остается, помимо исправления этой логики, так что она работает, объединяет эти функции вместе, чтобы сформировать функцию execute_ops
.
Вы не должны назвать свои функции insert
, delete
и setsize
, если эти значения являются одновременно значение Конструкторы вашего типа данных. Просто, как только вы определяете тип данных, а затем функции в той же области действия, функции будут теневыми над конструкторами значений и не смогут выразить значения типа list_op.
Важным, и я подозреваю, что запутанным является то, что insert
, delete
и setsize
не являются функциями, выполняющими операции над списками. Они конструкторы значений, так же как и leaf
node
предназначены для создания бинарного дерева:
datatype tree = leaf | node of tree*int*tree
Сравнение pos=h
в insert
не имеет смысла. Элемент в списке не совпадает с их позициями. Вы хотите вставить х на позицияpos
, а не на первый элемент, который равен , равныйpos
. Значение не обязательно равно его позиции в списке, в котором он встречается.
И delete
, к сожалению, совершенно бессмысленно; то, что говорит ваш код, является «если число n равно элементу в списке, а затем верните весь список. Else, удалите элемент и продолжайте удаление элементов до тех пор, пока это не произойдет, или список пуст».
Получение исключения в delete
также не требуется в соответствии с определением.
Я не уверен, что вы имеете в виду, не понимая, что такое настройка. Предполагается, что это операция, которая задает размер списка. Повторяя текст назначения, , если размер меньше текущей длины, удалите лишние элементы, в противном случае расширьте конец списка нулями.
Вот шаблон для решения задания:
datatype list_op = insert of int*int | delete of int | setsize of int
fun insert_h (0, elem, x::xs) = ... (* insert elem instead of x *)
| insert_h (pos, elem, []) = ... (* list was too short *)
| insert_h (pos, elem, x::xs) = ... (* not there yet *)
fun setsize_h (0, xs) = ... (* wonder what list has size 0 *)
| setsize_h (n, []) = ... (* extend list n times more *)
| setsize_h (n, x::xs) = ... (* not there yet *)
fun delete_h (0, x::xs) = ... (* delete element at this position *)
| delete_h (n, []) = ... (* list was too short *)
| delete_h (n, x::xs) = ... (* not there yet *)
fun execute_ops [] xs = ... (* no more operations to execute *)
| execute_ops (list_op::list_ops) xs =
let val new_xs = (case list_op of
insert (pos, elem) => insert_h (pos, elem, xs)
| delete pos => delete_h (pos, xs)
| setsize size => setsize_h (size, xs))
in execute_ops list_ops new_xs
end
Вы могли бы пожелать, чтобы проверить эти функции, либо изолированно, либо в сочетании с использованием execute_ops
:
val test_insert_h_1 = insert_h (2, 7, [1,2,3,4]) = [1,2,7,4]
val test_insert_h_2 = insert_h (9, 5, [1,2,3,4]) = [1,2,3,4,5]
val test_setsize_h_1 = setsize_h (2, [5,6,7,8]) = [5,6]
val test_setsize_h_2 = setsize_h (5, [1,2,3]) = [1,2,3,0,0]
val test_delete_h_1 = delete_h (3, [4,5,6,7,8]) = [4,5,6,8]
val test_delete_h_2 = delete_h (9, [1,2,3]) = [1,2,3]
val test_execute_ops_1 =
execute_ops [insert (0, 5), insert (1, 6), insert (2, 7)] [2,3,5] = [5,6,7]
val test_execute_ops_2 =
execute_ops [setsize 5, insert (4, 9)] [] = [0,0,0,0,9]
val test_execute_ops_3 =
execute_ops [setsize 6, insert (1, 5), delete 3] [8,8,8,8,9] = [8,5,8,9,0]