我是f#的新手
我试着计算一组数字的笛卡尔积.我"借"了这个.
let xs = [1..99]
let ys = [1..99]
seq {for x in xs do for y in ys do yield x * y}
Run Code Online (Sandbox Code Playgroud)
有更好或更优雅的方式吗?
加里
根据List模块提供的功能解决问题的另一个可能性是:
let xs = [1..99]
let ys = [1..99]
let zs = xs |> List.collect (fun x -> ys |> List.map (fun y -> x*y))
Run Code Online (Sandbox Code Playgroud)
这避免了对.concat的额外调用,也应该完成这项工作.
但我坚持你的解决方案.它应该是最可读的,是真正的对手.(只是试着大声读出这些代码.你的完全可以理解,Noldorins或我的不是.)
免责声明:我没有安装当前F#的机器,所以我无法测试我的代码.但是,基本上,如果你sequence
从Haskell 窃取,你可以编写你的程序
let cartesian = sequence >> List.map product
Run Code Online (Sandbox Code Playgroud)
并运行它
cartesian [[1..99]; [1..99]]
Run Code Online (Sandbox Code Playgroud)
这是写作的方法sequence
.它是您编写的序列表达式的通用版本.它只处理无限数量的列表:{ for x in xs do for y in ys do for z in zs ... yield [x;y;z;...] }
.
let rec sequence = function
| [] -> Seq.singleton []
| (l::ls) -> seq { for x in l do for xs in sequence ls do yield (x::xs) }
// also you'll need product to do the multiplication
let product = Seq.fold_left1 ( * )
Run Code Online (Sandbox Code Playgroud)
然后你可以编写你的程序
let cartesian xs ys = [xs; ys] |> sequence |> List.map product
// ... or one-argument, point-free style:
let cartesian' = sequence >> Seq.map product
Run Code Online (Sandbox Code Playgroud)
您可能需要将某些Seq
s 更改为List
s.
但是,能够猜出非一般列表理解含义的人数可能比识别名称要多得多sequence
,所以你可能更适合使用列表理解.sequence
但是,只要您想运行整个计算表达式列表,它就会派上用场.