多种输入类型,带折叠

时间:2016-02-08 08:37:28

标签: sml fold ml

我试图弄清楚如何在不同类型的输入上实现折叠函数。作为一个示例,我将使用count函数作为列表(但是,我有多个函数可以实现)。 假设一个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列表是集合的Universe,bool确定集合中的Universe值。即,(1,3,5,6),(真,假,假,真)导致最终集合(1,6),其计数为2.我首先想到尝试这个是某种形式的

val count= foldr (fn(x:(int*bool),y)=>if #2x then y+1 else y ) 0 ;

但这导致返回类型为

val count = fn : (int * bool) list -> int

这不是我需要的。从逻辑上讲,它们是相似的,但我希望将这两种类型组合在一起。

1 个答案:

答案 0 :(得分:2)

  1. 您可以使用ListPair.foldl

    fun count (xs, bs) = ListPair.foldl (fn (x, b, acc) => ...) ... (xs, bs)
    

    其中第一个...xbacc的某种组合,第二个...是初始值。

    这假设xsbs同样长,如果不是,则丢弃较长列表中的其余元素。 (在xsbs的任何一种情况下,如果这给出了正确答案,你应该试着证明是正确的。)

  2. 否则,您需要通过组合一个函数将 int list×bool list 组合(也称为zip)到(int×bool)列表中两个列表,并将此功能与您正在进行的折叠结合使用。

    fun combine (x::xs, y::ys) = ...
      | combine (..., ...) = ...
    

    此功能可以等同于ListPair.zip