Могу ли я избежать этого кастинга в F #? - PullRequest
0 голосов
/ 24 мая 2018

Контекст этого вопроса - raytracer, который я пишу.

У меня есть тип Surface, в идеале мне нужен абстрактный базовый класс, от которого наследуются NoSurface и Lambertian.

Однако, когда у меня есть эта иерархия, у меня возникает следующая проблема:

    let closestIntersection : bool*LineParameter*Surface = 
    match allIntersectionsWithRealSolutions with 
        | [] -> (false,0.0f, NoSurface(0UL,NotHitable(),Material(Vector3.Zero)))
        | x::xs -> List.reduce (fun smallest current -> smallestIntersection smallest current) allIntersectionsWithRealSolutions

Это выдает ошибку компилятора , поскольку тип, с которым он связывает возвращаемый тип, - NoSurface,даже при указании типа в качестве Surface.

Это решило проблему:

    let closestIntersection : bool*LineParameter*Surface = 
    match allIntersectionsWithRealSolutions with 
        | [] -> (false,0.0f, NoSurface(0UL,NotHitable(),Material(Vector3.Zero)) :> Surface)
        | x::xs -> List.reduce (fun smallest current -> smallestIntersection smallest current) allIntersectionsWithRealSolutions
closestIntersection

Но приведение :> стоит мне 25 мс согласно BenchmarkDotNet по сравнению с решением определения Surface как (не абстрактный) класс и просто возвращает его вместо этого!

Могу ли я как-то избежать явного приведения и иметь желаемую иерархию Существа Поверхности и абстрактного класса?

1 Ответ

0 голосов
/ 24 мая 2018

Вы можете попытаться решить ту же проблему, используя различающиеся союзы, что было бы более «функциональным» способом, так как вы используете F # ?.Хотя я несколько уверен, что этот подход может быть немного медленнее.Но если вам нужна максимальная производительность, управляемый язык - не лучший выбор для начала.Найдите хорошее объяснение профсоюзов на https://fsharpforfunandprofit.com/posts/discriminated-unions/

, чтобы что-то вроде этого.

type Intersectable =
    | Sphere of center:Point3 * radius:float
    | Triangle of v0:Point3 * v1:Point3 * v2:Point3
    | MeshTriangle of faceIndex:int * mesh:Mesh
    | Instance of Intersectable * Matrix.Matrix4x4
    | Plane of normal:Vec3 * pointOnPlane: Point3

общие / общие функциональные возможности можно было использовать с помощью общих частей данных, на которые действуют ваши функции, возможно, у вас:

type Shape = {
    geometry: Intersectable
    material: Material }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...