2

私は、F# レコードのリストで構成されるデータ構造を持っています。そのメンバー自体の 1 つは、異なるタイプのレコードのリストであり、約 4 レベルの深い階層まで続きます。この構造を作成するために必要なコードは少し冗長ですが、機能します。ここで、このデータ構造のリストを階層の最上位から分解して、階層の最下位レベルのリスト内のアイテム数のカウント数のマップを生成する一般的な末尾再帰関数を作成したいと思います。階層の各レベルでレコードを分解する関数を作成することで必要なコードを開発できますが、リストを処理するために同じ再帰関数を使用することになりますが、レコードの種類は異なります。以下は、これを冗長ではない方法で実装しようとした方法ですが、次のエラーが発生します。

このランタイム強制または型テスト from type
    'a
to に
    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 

しかし、私はジョン・パーマーのコメントに完全に同意します.

于 2012-08-08T09:08:14.500 に答える