2009-07-24 15 views
0

私はF#で海図の深度曲線を表現するための構造体を作成しようとしています。それは、座標のリストと、どの深さが表現されているかを示す浮動小数点(例えば、「4.5メートル」)を含んでいなければならない。私はそれをこのように作られています海の地図の深度曲線の構造

type Coord = 
    struct 
     val X : float 
     val Y : float 
     new(x,y) = { X = x ; Y = y } 
    end 

type DepthCurve = 
    struct 
     val Coords : list<Coord> 
     val Depth : float 
     new(list_of_Coords, depth) = { Coords = list_of_Coords ; Depth = depth} 
    end 

let myCoord1 = new Coord(1.,2.) 
let myCoord2 = new Coord(3.,4.) 
let myDepthCurve = new DepthCurve([myCoord1;myCoord2] , 5.) 

私の問題は、これは私が一度に多角形とそのCOORDSを作成することはできませんということで、次のように:

let myDepthCurve = {coords=[[1.;2.];[3.;4.]] , 5} 

のためのソリューションが存在しますかこの:

type Coord = { X : float; Y : float } 
type 'a DepthCurve = {coords: 'a list;} 
let myDepthCurve = {coords=[[1.;2.];[3.;4.]]};; 

が、それは私が同様に構造体の深さを示すフロートを持たせていない、そしてそれは私が唯一のCOORDSするリストの種類を制限することはできません。

どのようにすれば両方の世界のベストを組み合わせることができますか?

答えて

1

作成したオブジェクトタイプは、コンストラクタを持つ標準の.NET構造です。特殊なF#-record-initialization sytnax({ ... })はありません。あなたの問題のために

、あなたはほんの少しのラッパー関数を書くことができ:

この

let testCurve = curve 10. [(1., 2.); (3., 4.); ...] 

短縮レコード構文であなたの構造体を宣言するとき、あなたはこのようにそれを行う必要がありますように使用

let curve depth coords = New DepthCurve([for (x, y) in coords -> New Coord(x, y)], depth) 

type Coord = float * float // Type-alias for a 2D-float-tuple 
type DepthCurve = { coords : Coord list; depth : float } 

let myCurve = { coords = [(1., 2.); ...], depth = 42. } 

ジェネリックリストを使用する理由はありませんCoord list(意味はList of Coords)と指定します。リスト([1; 2; 3])とタプル((1, 2, 3))の違いに注意してください。後者は、指針を表すのにはるかに適しています。

F#の構造とタイプについてはthis articleをご覧ください。

+0

を。これは短い記法とチーズを持っています。 – loldrup

+0

... VS 2008で動作しない点を除いて。 – loldrup

+0

myCurveのcoordsとdepthのメンバーを区切るカンマは、セミコロンでなければなりません。 – kvb

0

答えは、プログラムを構成する方法によって異なります。私は3つの選択肢に投票あなたがactivly機能パラダイム(変異なし、高次機能、パターンマッチング)を使用する場合については

:ケースのために

(* tuple with type constractor and any getters you need: *) 
let makeCoord x y = (x,y) 
let makeCurve depth coords = (depth,coords) 
let addCurveCoord (depth,coords) coord = (depth, coord::coords) 
let getCurveDepth (depth,_) = depth 
let getCurveCoords (_,coords) = coords 
let getFirstCurveCoord (_,coords) = List.hd coords 
//... 

(* or types described by Dario *) 
(* or tagged unions for case you need specific access to parts of your data *) 

あなたは、単純なオブジェクト階層を作成することができOOPを好みます。

FPの主な利点は、プログラムの任意のステップでデザインを簡単に変更できることです。しかしもちろん、それは明示的な国家主張であなたにかかる費用です。しかし、モナド式で彼らを倒すこと:)

+0

私は関数型プログラミングを好む:) 私はあなたの提案をすぐに調べます – loldrup

+0

あなたの機能的な解決策についての心配は、明示的な型がないことです。曲線のように見えるものは何でもあります。 – loldrup

+0

類似したデータ構造を多く持つ場合、タグ付きタプルは最善の選択ではありませんが、タイプとタグ付きユニオンを使用できます:) – ssp

-1

ダリオへ:

私はVS 2008でこれを書くとき:

type Coord = float * float // Type-alias for a 2D-float-tuple 
type DepthCurve = { coords : Coord list; depth : float } 

let myCurve = { coords = [(1., 2.); (3., 4.)], depth = 42. } 

私はtheeseエラーを取得:これは本当にいいです

This expression has type 'a * 'b but is here used with type Coord list 
no assignment given for field 'depth' 
+0

myCurveで座標と奥行きのメンバーを区切るカンマはセミコロンでなければなりません。 – kvb