带折叠的多种输入类型
Multiple input types with fold
我想弄清楚如何在不同类型的输入上实现折叠功能。作为示例,我将对列表使用计数函数(不过,我有多个函数可以为此实现)。
假设一个 int 列表输入(尽管这应该适用于任何类型的列表),我的计数函数将是
val count = foldr (fn(x:int,y)=>y+1) 0 ;
val count = fn : int list -> int
但是,我正在尝试创建类型为
的计数函数
val count = fn : int list * bool list -> int
其中int列表是集合的全域,bool决定全域的哪些值在集合中。即,(1,3,5,6),(true,false,false,true) 结果是最后一组 (1,6),其计数为 2。我首先想到的是某种形式
val count= foldr (fn(x:(int*bool),y)=>if #2x then y+1 else y ) 0 ;
但这会导致 return 类型的
val count = fn : (int * bool) list -> int
这不是我需要的。从逻辑上讲,它们是相似的,但我希望将这两种类型分别组合在一个列表中。
您可以使用 ListPair.foldl
:
fun count (xs, bs) = ListPair.foldl (fn (x, b, acc) => ...) ... (xs, bs)
其中第一个 ...
是 x
、b
和 acc
的某种组合,第二个 ...
是初始值。
这假定 xs
和 bs
的长度相同,如果不是,则丢弃较长列表中的剩余元素。 (您可能应该尝试证明在 xs
或 bs
更长的情况下是否给出了正确答案。)
否则,您需要将 int 列表 × bool 列表 合并(也称为 zip)到 (int × bool) 列表 通过制作一个组合两个列表的函数,并将此函数与您已经在做的折叠结合使用。
fun combine (x::xs, y::ys) = ...
| combine (..., ...) = ...
这个函数可以等效于ListPair.zip
.
我想弄清楚如何在不同类型的输入上实现折叠功能。作为示例,我将对列表使用计数函数(不过,我有多个函数可以为此实现)。 假设一个 int 列表输入(尽管这应该适用于任何类型的列表),我的计数函数将是
val count = foldr (fn(x:int,y)=>y+1) 0 ;
val count = fn : int list -> int
但是,我正在尝试创建类型为
的计数函数val count = fn : int list * bool list -> int
其中int列表是集合的全域,bool决定全域的哪些值在集合中。即,(1,3,5,6),(true,false,false,true) 结果是最后一组 (1,6),其计数为 2。我首先想到的是某种形式
val count= foldr (fn(x:(int*bool),y)=>if #2x then y+1 else y ) 0 ;
但这会导致 return 类型的
val count = fn : (int * bool) list -> int
这不是我需要的。从逻辑上讲,它们是相似的,但我希望将这两种类型分别组合在一个列表中。
您可以使用
ListPair.foldl
:fun count (xs, bs) = ListPair.foldl (fn (x, b, acc) => ...) ... (xs, bs)
其中第一个
...
是x
、b
和acc
的某种组合,第二个...
是初始值。这假定
xs
和bs
的长度相同,如果不是,则丢弃较长列表中的剩余元素。 (您可能应该尝试证明在xs
或bs
更长的情况下是否给出了正确答案。)否则,您需要将 int 列表 × bool 列表 合并(也称为 zip)到 (int × bool) 列表 通过制作一个组合两个列表的函数,并将此函数与您已经在做的折叠结合使用。
fun combine (x::xs, y::ys) = ... | combine (..., ...) = ...
这个函数可以等效于
ListPair.zip
.