首页 > 解决方案 > F#:如何检查序列内容的序列?

问题描述

我想生成一组元组序列的序列

用于生成棋盘游戏中线的坐标(正方形);水平线、垂直线和主要的 2 条对角线

我使用列表(使用 generateLines 函数)创建的那个效果很好。它在元组列表列表中生成行的坐标。但是,在将其转换为序列序列后,我不知道如何检查它是否正确

我试过这个: CoordinateLines 3 |> Seq.map (fun x ->Seq.toList) |> Seq.toList

但它不起作用,出现错误:错误 FS0030:值限制。值 'it' 已被推断为具有通用类型 val it : ('_a -> '_b list) list when '_a :> seq<'_b>
将 'it' 定义为简单的数据项,使其成为函数使用显式参数,或者,如果您不希望它是通用的,请添加类型注释。

let CoordinateLines size : seq<seq<int*int>> =  
    let generateLines size = 
        [for a in 0..(size-1) do

        yield [for b in 0..(size-1) do
        yield(a,b)
        ]
        ]
        @
        [for a in 0..(size-1) do

        yield [for b in 0..(size-1) do
        yield(b,a)
        ]
        ] 
        @
        [[for a = 0 to (size-1) do
        yield (a,(size-1)-a)

        ]]
        @
        [[for a = 0 to (size-1) do
        yield (a,a)
        ]]
    generateLines size 
    |> List.toSeq 
    |> Seq.map (fun x -> List.toSeq x)

标签: f#

解决方案


您收到此错误,因为您忘记在传递给的 lambda 函数中x作为参数传递给. 以下工作正常:Seq.toListSeq.map

CoordinateLines 3 |> Seq.map (fun x ->Seq.toList x) |> Seq.toList

或者,您也可以Seq.toList直接用作 的参数Seq.map

CoordinateLines 3 |> Seq.map Seq.toList |> Seq.toList

也就是说,我看不出有任何理由将列表转换为seq<'a>- 列表类型seq<'a>已经实现了接口,因此您想要对序列执行的任何操作也适用于列表。而且由于您已经生成了完全评估的列表,实际上可能会证明您可以使用列表更好地编写一些后续逻辑。

如果我这样做,我只需编写一个返回列表列表的函数。您还可以使用
[ for <var> in <range> -> <expr> ]符号(它可以让您省略一些yield关键字),并且您可以@通过将所有生成嵌套列表的代码放在一个[ .. ]包含多个嵌套fors 和yields 的大块中来避免使用。这使您的代码更短:

let CoordinateLines size =  
    [ for a in 0..(size-1) ->
        [ for b in 0..(size-1) -> (a,b) ] 
      for a in 0..(size-1) ->
        [ for b in 0..(size-1) -> (b,a) ] 
      yield [ for a in 0..(size-1) -> (a,(size-1)-a) ] 
      yield [ for a in 0..(size-1) -> (a,a) ] ]

推荐阅读