为什么我不能压缩两个不同长度的列表?

Sol*_*lma 6 zip f# list

在F#中如果试图压缩两个不同长度的列表,则会出现错误:

List.zip [1..4] [1..3]
// System.ArgumentException: The lists had different lengths.
Run Code Online (Sandbox Code Playgroud)

但是,定义zip的替代定义非常容易,它接受两个不同长度的参数列表:

let rec zip' (xs: 'T list) (ys: 'T list) =
        match (xs, ys) with
        | ([], _) -> []
        | (_, []) -> []
        | ((z::zs), (w::ws)) -> (z, w) :: zip' zs ws

zip' [1..4] [1..3]
// val it : (int * int) list = [(1, 1); (2, 2); (3, 3)]
Run Code Online (Sandbox Code Playgroud)

是否有充分的理由不使用这种替代定义?为什么不首先采用它?

Tom*_*cek 11

实际上,这有点令人困惑,因为List.zip(不允许这样)和Seq.zip(截断较长列表)之间存在不匹配.

  • 我认为zip仅适用于长度相等的列表是一种合理的默认行为 - 如果它自动截断数据,那么在使用时zip可能会意外丢失一些有用的数据,这可能会导致细微的错误.

  • Seq.zip截断较长列表的事实只是合理的,因为序列是懒惰的,因此,在设计时,当我定义一个序列时,我希望消费者可能不会全部读取它.

总而言之,我认为行为差异是基于"对于给定的数据结构最明智的事情是什么",但我确实认为有两个操作名称会比调用两个名称更有意义zip(唉,那是现在几乎无法改变).