2

我有一个数据结构,它由一个 F# 记录列表组成,其中一个成员本身是一个不同类型的记录列表,直到大约 4 级深层次结构。我必须创建这个结构的代码有点冗长但有效。我现在希望创建一个通用的尾递归函数,该函数从层次结构的顶层分解此数据结构的列表,以生成一个映射,该映射是层次结构列表底层项目数的计数。我可以通过创建函数来开发所需的代码来分解层次结构中每个级别的记录,但最终你会得到相同的递归函数来处理列表,但记录类型不同。以下是我尝试以非详细方式实现此功能的方法,但出现以下错误:

此运行时强制或类型测试从类型
    'a

    MarshallingPanel
涉及基于此程序点之前的信息的不确定类型。某些类型不允许运行时类型测试。

我知道错误是 F# 中的类型推断,并且我可以找到的类型测试模式匹配示例涉及基类引用或可区分联合。我将尝试一个联合,如果这不起作用,请详细说明,但如果你们中的任何一个 F# 大师有要遵循的模式或任何输入都会很棒。

let rec mapAsRequired items (currentCBMap: Map<string*string*string*string, int>) =
    match items with
        | head :: tail ->
            match head with
                | :? MarshallingPanel as marshallingPanel ->
                        mapAsRequired marshallingPanel.PLCs currentCBMap
                | :? PLC as plc ->
                        mapAsRequired plc.Racks currentCBMap
                | :? Rack as rack ->
                        mapAsRequired rack.Slots currentCBMap
                | _ ->
                    mapAsRequired [] currentCBMap
            mapAsRequired tail currentCBMap
        | [] ->
            currentCBMap

let rec mapMarshallingPanels (marshallingPanels:MarshallingPanel list) (currentCBMap: Map<string*string*string*string, int>) = 
    match marshallingPanels with
        | head :: tail ->
            mapMarshallingPanels tail (mapAsRequired (List.sortBy(fun (plc:PLC) -> rankProcessorForCBAlllocation plc.PLCNo) head.PLCs) currentCBMap)
        | [] ->
            currentCBMap

mapAsRequired marshallingPanels Map.empty
4

1 回答 1

3

要解决此问题,您需要匹配类型obj而不是不确定类型(类型参数'a)的值。您可以通过添加box

match box head with 
| :? MarshallingPanel as marshallingPanel -> 
    mapAsRequired marshallingPanel.PLCs currentCBMap 
| :? PLC as plc -> 
    mapAsRequired plc.Racks currentCBMap 

但是,我完全同意 John Palmer 的评论,即使用有区别的工会似乎是您的目的更好的选择。

于 2012-08-08T09:08:14.500 回答