我试图通过两个列表“加倍”过滤,具体取决于使用HOP进行数据类型测试而不递归。以下是我对解决方案的非常丑陋的尝试......
datatype 'a test = Test of ('a -> bool) * string;
fun foo xs lst =
let
fun foo_bar(x, ls) =
let
val tests = (List.filter (fn (Test(f, str)) => (f x)) ls)
in
(List.map (fn (Test(f, str)) => str) tests)
end
in
(List.map (fn x => foo_bar(x, lst)) xs)
end;
allPass: 'a list -> 'a test list -> 'a test list;
allPass [1, 2, 40, 150] [positive, even]
应该返回字符串"pos"
。
目前,我的函数正在返回一个嵌套列表:[["pos"], ["pos even"], ["pos even"], ["pos even"]]
。是否有一种非递归的方法从这个结果中提取“pos”,或者我是否会在完全错误的方向上解决这个问题?
答案 0 :(得分:0)
你正朝着正确的方向前进,但你还没到那里。这就是我想你想要的。
获取值列表和测试列表。返回所有值传递的测试名称列表。
好的,我们需要:
好的,那么我们如何判断列表中的所有值是否通过一次测试?很简单,我们使用List.all
。
List.all : ('a -> bool) -> 'a list -> bool
我们可以定义一个函数:
fun allPassesTest xs (Test(f,s)) = List.all f xs
当且仅当xs中的所有值都通过测试时,这将返回true
。现在我们根据这个函数过滤测试列表:
fun allPass xs tests = List.filter allPassesTest xs tests
但是,这会返回'a test list
而不是string list
,因此您需要提取名称。
fun name (Test(f,s)) = s
fun allPass xs tests = map name (List.filter allPassesTest xs tests)