Последствия в ML (конечные и бесконечные) - PullRequest
2 голосов
/ 07 января 2011

Хорошо,

У меня есть следующее определение последовательности:

datatype 'a seq = Nil | Cons of 'a * (unit-> 'a seq);

Мне нужно реализовать следующую функцию:

filterq_n:('a -> bool) -> int -> 'a seq -> 'a seq

Функция получаетфункция предиката, которая возвращает истину или ложь, n (целое число) и последовательность.

Функциональность:

  1. , если n <= 0, возвращает тот же результат.</li>
  2. иначе возвращает seq, что его первые n элементов являются первыми n элементами в оригинальном seq, который предикат возвращает для них true, а остальные будут такими же.

Например, если предикат (x mod 2) и seq равен 1,2,3,4,5 ... и n равен 3, значит, новый seq равен 2,4,6,7,8, ...

Кроме того, я должен проверить еще 2 параметра:

2.1), если seq конечен и имеет менее n элементов, которые предикат возвращает true для них, тогда новый seq будет содержать только элементы, которые предикат, возвращают для них true.

2.2) если seq бесконечен и имеет менее n элементов, которые предикат возвращает true для них, тогда новый seq будет содержать все элементыэтот предикат возвращает true для них, и при попытке получить следующий элемент он войдет в бесконечный цикл.

Мой текущий код логически был запланирован на данный момент без учета 2.1 и 2.2 (хотя я получаю ошибки и могу найти причину?)

fun     filter_n (predicate: 'a -> bool ) (n: int)  Nil = Nil
|       filter_n (predicate: 'a -> bool ) (n: int) (Cons(x, xf)) =      
            if(n <= 0)  then Cons(x, xf) 
                        else 
                            if predicate x then Cons(x, fn() => filter_n predicate n-1 (xf()) ) 
                            else  filter_n predicate n-1 (xf())  
;

синтаксические ошибки или радикальные изменения .. Я не уверен?

(также для 2.1 и 2.2 мне просто нужно проверить, что если я получил (Nil и n> 0), то вернуть Nil?)

Заранее спасибо за любую помощь.

1 Ответ

1 голос
/ 07 января 2011

Вам нужно заключить в скобки n-1, иначе это будет интерпретировано как несколько аргументов. После того, как вы это сделали, он скомпилируется.

Однако в вашем коде все еще есть логическая ошибка: вы уменьшаете n независимо от того, соответствует предикат или нет. Однако в спецификации говорится, что вы должны выбирать n элементов, где предикат соответствует, а не то, что вы должны проверять предикат для n элементов. Таким образом, вы должны уменьшать n, только если предикат совпадает, и сохранять то же самое n в противном случае.

Как только вы исправите это, ваш код должен соответствовать спецификации (включая 2.1 и 2.2).

...