F#是否与Haskell相当?

McM*_*ons 14 f# haskell list

在Haskell中,有一个函数"take n list",它返回列表中的前n个元素.例如,"sum(take 3 xs)"总结了列表xs中的前三个元素.F#有同等价值吗?我希望它是List函数之一,但我找不到任何似乎匹配的东西.

Tom*_*cek 44

为了澄清一些事情,之间的区别Seq.take,并Seq.truncate(通过@ sepp2k指出)是第二个会给你一个返回序列最多指定元素的数量(但如果该序列的长度短,它会给你更少的元素).

Seq.take如果您尝试访问超出原始列表长度的元素,则序列生成函数将抛出异常(请注意,该Seq.take函数不会立即抛出异常,因为结果是延迟生成的序列).

此外,您不需要显式将列表转换为序列.在封面下,list<'a>是一个继承自seq<'a>类型的.NET类,它是一个接口.该类型seq<'a>实际上只是一个类型别名IEnumerable<'a>,因此它由所有其他集合(包括数组,可变列表等)实现.以下代码可以正常工作:

let list = [ 1 .. 10 ]
let res = list |> Seq.take 5
Run Code Online (Sandbox Code Playgroud)

但是,如果要获取类型的结果,则list<int>需要将序列转换回列表(因为列表的类型比序列更具体):

let resList = res |> List.ofSeq
Run Code Online (Sandbox Code Playgroud)

我不确定为什么F#库不提供List.takeList.truncate.我想我的目标是避免为所有类型的集合重新实现整个函数集,所以那些在使用更具体的集合类型时序列的实现足够好的那些只在Seq模块中可用(但这只是我的猜测. ..)


Jor*_*ren 16

是的,它被称为Seq.take.用法似乎与Haskell的相同:Seq.take count source.要在列表中使用它,List.toSeq请先使用.(更新:显然,从评论来看,这不是必需的.)

  • 实际上,haskell的行为就像Seq.truncate,而不是Seq.take. (15认同)
  • 由于列表继承自IEnumerable,因此您无需先从我看到的内容将其转换为序列.在列表上使用Seq.take工作正常. (2认同)