F#クラスの並べ替えのVisual Studio

私の型の階層がVisual Studioで型の順序で動作しないサンプルアプリケーションをビルドする。どのような方法でファイルを整理しようとしても(上、下)、すべてのクラスを定義することはできません。

だから彼らはf#プロジェクトの順序で

type Artist() =
    let mutable artistId = 0
    let mutable name = String.Empty

    member x.ArtistId 
        with get() = artistId
        and set (value) = artistId <- value

    member x.Name
        with get() = name
        and set ( value ) = name <- value

type Genre() =
    let mutable name = String.Empty
    let mutable genreId = 0
    let mutable description = String.Empty
    let mutable albums = [new Album()]

    member x.Name 
        with get() = name
        and set (value) = name <- value

    member x.GenreId
        with get() = genreId
        and set ( value ) = genreId <- value

    member x.Description
        with get() = description
        and set ( value ) = description <- value

    member x.Albums
        with get() = albums
        and set ( value ) = albums <- value

and Album() =
    let mutable title = String.Empty
    let mutable genre = new Genre()
    let mutable albumId = 0
    let mutable genreId = 0
    let mutable artistId = 0
    let mutable price : decimal = Decimal.Zero
    let mutable albumArtUrl = String.Empty
    let mutable artist = new Artist()

    member x.Title
        with get() = title
        and set (value) = title <- value

    member x.Genre
        with get() = genre
        and set (value) = genre <- value

    member x.AlbumId
        with get() = albumId
        and set ( value ) = albumId <- value

    member x.GenreId
        with get() = genreId
        and set ( value ) = genreId <- value

    member x.ArtistId
        with get() = artistId
        and set ( value ) = artistId <- value

    member x.Price
        with get() = price
        and set ( value ) = price <- value

    member x.AlbumArtUrl
        with get() = albumArtUrl
        and set ( value ) = albumArtUrl <- value 

    member x.Artist 
        with get() = artist
        and set ( value ) = artist <- value

だから上のケースで私はエラー "アルバム"が定義されていない得る。

これを解決する方法はありますか?それとも、私のタイプの階層構造の全体を再考する必要がありますか?

1
快適なコンピュータの近くでは完全な答えを書くことはできませんが、同じモジュール/名前空間に型を入れると、相互に再帰的な型を持つことができます。それらを順番に並べて、2番目の "type"キーワードをキーワード "and"に置き換えてください。 F#の種類に関するMSDNの記事に行くと、より完全な説明が得られます。
追加された 著者 Ramon Snir,
だから基本的にジャンルのタイプにはアルバムとアルバムのタイプがフィールドとしてジャンルを含んでいます。 F#でこのような階層を定義することは、何とか可能ですか?
追加された 著者 netmatrix01,

1 答え

相互に再帰的な(相互に参照できるという意味)という2つの型を定義する必要がある場合は、それらを単一のファイルに配置し、 type ... ... の構文を使用します。

あなたの例では、これは Genre Album を次のように定義する必要があることを意味します。

// Start a definition block using 'type' as normal
type Genre() =  
  let mutable name = String.Empty 
  let mutable albums = [new Album()] 

  member x.Name  
      with get() = name 
      and set (value) = name <- value 
  member x.Albums 
      with get() = albums 
      and set ( value ) = albums <- value 

// Continue single type definition block using 'and'
and Album() = 
    let mutable genre = new Genre() 
    let mutable albumId = 0 
    let mutable artist = new Artist() 

    member x.Genre 
        with get() = genre 
        and set (value) = genre <- value      
    member x.AlbumId 
        with get() = albumId 
        and set ( value ) = albumId <- value      
    member x.Artist  
        with get() = artist 
        and set ( value ) = artist <- value 

しかし、あなたの例では非常にC#スタイルでF#を使用しているので、コードは実際には非常にエレガントではなく、関数型プログラミングの利点の多くを与えるわけではありません。

あなたが使っている構造を表現したいのであれば、そのジャンルへの参照を Album 型に追加しないでしょう。 Genre の中にアルバムのリストを置くと、データ構造を処理するときに(つまり、他の構造、おそらくF#レコードに変換することができます。データバインディングに渡す必要があります)。 F#の恩恵は、ドメインを数行書くことができるということですが、それは機能型に対してのみ機能します。

区別された共用体を単一のケースで使用すると、次のように書くことができます。

// Type aliases to make code more readable
type Name = string
type AlbumID = int

// Simple type definitions to represent the domain
type Artist = Artist of Name
type Album = Album of AlbumID * Artist
type Genre = Genre of Name * Album list
5
追加された
@ netmatrix01大きなプロジェクトでは、インターフェースを使用する必要があります。 Genre Album を(1つのファイルで)インタフェースとして定義し、実際の実装をより多くのファイルに分割してこれらのインタフェースを参照することができます。
追加された 著者 Tomas Petricek,
ああ、クール、それを試みることを考えていた、私はそれを以前のどこかで、忘れてしまったのを読んだと思う。どうもありがとう
追加された 著者 netmatrix01,
しかし、私たちは別々のファイルでも型を分離するよりクリーンな方法を取るべきだと思います。今のところうまくいきません。大きなファイルが複雑であるかもしれないと思っています。
追加された 著者 netmatrix01,
うん、確かに意味がある、ありがとう
追加された 著者 netmatrix01,
差別化されたユニオンの方法は、あまりにもすてきで素敵です。
追加された 著者 netmatrix01,
ご迷惑をおかけして申し訳ありませんが、私が新しく編集したデータ構造について説明してください。どうすれば差別化されたユニオン/もっとF#の方法でそれを定義できますか?私は私のコードは基本的にC#の方法で、機能的な方法をゆっくりと学習しようとしていることに同意する。
追加された 著者 netmatrix01,