Как я могу реализовать 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