2011-12-21 11 views
3
type node = { 
    lan: string; 
    lat: string; 
};; 

let rec read_nodes_from_list list = match list with 
    | Xml.Element("node", _, _)::list' -> {lan="A"; lat="B"}::read_nodes_from_list list' 
;; 

ノードレコードを作成しようとしましたが、動作しません。そして、ノードの属性が同じである別の型があるとします。どの型のオブジェクトを作成するにはどうしたらいいですか?OCaml:関数からレコードを作成する

ありがとうございます。あなたは空のリストと一致するのを忘れているため

答えて

6

明らかに、あなたの機能は動作しませんでした:

let rec read_nodes_from_list list = match list with 
    | Xml.Element("node", _, _)::list' -> {lan="A"; lat="B"}::read_nodes_from_list list' 
    | [] -> [] 

は、あなたが実際にやろうとしているのは、リスト上のmap操作ですので、あなたの機能は多くを書くことができエレガントとしては、以下:Xml.Element上のパターンマッチングは網羅的ではないので

let read_nodes_from_list list = 
    List.map (fun (Xml.Element("node", _, _)) -> {lan="A"; lat="B"}) list 

しかし、機能が動作しない場合があります。残りのケースを扱うときは注意が必要です。例えば、このようなものは動作します:

let read_nodes_from_list list = 
    List.map (function | (Xml.Element("node", _, _)) -> {lan="A"; lat="B"} 
         | _ -> {lan=""; lat=""}) list 

レコードの種類についてのご質問に答えるために、それは同じフィールドラベルを持つ2つのレコードタイプを持っている悪い習慣を考慮しています。 これらのレコードタイプを異なるサブモジュールに配置して、モジュール接頭辞を使用して区別することができます。しかし、私が言ったように、同じモジュールに2つの同様のレコードタイプを持つと、あなたとOCamlコンパイラに混乱が生じます。

+0

ありがとうございました!同じ属性を持つ2つの型がある場合、どの型のオブジェクトを作成するかをocamlにどのように伝えることができますか? – Steve

+0

これらは異なるモジュール(サブまたはそれ以外)でなければならず、前述の混乱が開かれないようにする必要があります。それぞれは '{X.attr1 = ...;}の通常のモジュール接頭辞構文で参照できます。 att2 = ...;} '与えられたモジュール' X'に対して。 – nlucaroni

関連する問題