Изменение порядка классов F # в Visual Studio - PullRequest
1 голос
/ 06 февраля 2012

Я создаю пример приложения, в котором моя иерархия типов не работает с упорядочением типов в 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 Ответ

5 голосов
/ 06 февраля 2012

Если вам нужно определить два типа, которые являются взаимно рекурсивными (что означает, что они могут ссылаться друг на друга), то вам нужно поместить их в один файл и использовать синтаксис type ... and ....

В вашем примере это означает, что 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 

Однако ваш пример использует F # в очень C # -стиле, поэтомукод на самом деле выглядит не очень элегантно и может не дать вам многих преимуществ функционального программирования.

Если бы я хотел представить структуру, которую вы используете, то, вероятно, я бы не добавил ссылку на жанр в тип 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...