Как я могу реализовать multiFilter со списком типов данных в ML

datatype 'a Multilist = 
   Node of 'a list
 | List of 'a Multilist list;

fun isGreaterThen x y = y > x;

fun multiFilter  f (List([])) = []  
  | multiFilter  f  (List(m::multil)) = 
    let fun flattenAuxiliray(Node(value)) = 
                   if (f value = true) then (value) else nil
          | flattenAuxiliray((List(nil))) = nil
          | flattenAuxiliray(List(m::mlist1)) = (flattenAuxiliray(m)) @ 
                   (flattenAuxiliray((List(mlist1)))) 
    in (flattenAuxiliray(m)) @ (multiFilter f (List(multil)))
    end;

Я получаю ошибку на этом входе:

val l = List [Node [3,5,18], Node [7]];
multiFilter (isGreaterThen 6) l;

stdIn:7.1-8.46 Error: operator and operand don't agree [tycon mismatch]
  operator domain: ('Z list -> bool) * 'Z list Multilist
  operand:         (int -> bool) * int list Multilist
  in expression:
    multiFilter (isGreaterThen 6,List (Node <exp> :: <exp> :: <exp>))

выход:

val it = [18,7] : int list

2 ответа

Ваша ошибка типа говорит, что первый параметр ожидает что-то типа 'Z list -> boolЭто означает, что это функция, которая принимает полиморфный список и возвращает bool. Тем не менее, вы предоставляете функцию, которая принимает int и возвращает бул. Вместо этого следует взять в списке intи вернуть bool, Вы можете достичь этого, изменив isGreaterThan (типа int -> int -> bool) к чему-то типа int -> int list -> bool, который будет сравнивать все в списке с первым параметром, возвращая true только тогда, когда все элементы меньше.

Ваша проблема имеет корень здесь:

flattenAuxiliray(Node(value)) = 
                   if (f value = true) then (value) else nil

Ваш тип данных говорит Node of 'a list так value должен быть 'a list,
Поскольку вы подаете заявку f в value, f должен иметь тип 'a list -> bool, но вы проходите мимо isGreaterThan 6, который имеет тип int -> bool,

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

flattenAuxiliray (Node value) = 
                   List.filter f value

(Примечание: из-за обилия скобок и недостатка пробела SML очень трудно читать. Помните, что большую часть времени код тратит не написано и не выполнено, но читается людьми.)

Полная функция:

fun multiFilter  f (List []) = []  
  | multiFilter  f (List (m::multil)) = 
    let fun flattenAuxiliary (Node ls) = List.filter f ls
          | flattenAuxiliary (List []) = []
          | flattenAuxiliary (List (m::mlist1))
            = (flattenAuxiliary m) @ (flattenAuxiliary (List mlist1)) 
    in (flattenAuxiliary m) @ (multiFilter f (List multil))
    end;

Взаимодействие:

- multiFilter (isGreaterThan 6) (List [Node [3,5,18],Node [7]]);
val it = [18,7] : int list
Другие вопросы по тегам