2015-07-06 3 views
10

Я программировал в F # в течение нескольких лет, и есть «проблема», которая беспокоила меня в течение некоторого времени, и я не смог ее решить. Это не ошибка, я думаю, что это дизайнерское решение, но в любом случае проблема заключается в следующем: есть ли способ задержать (может быть, это не правильное слово для этого) реализация интерфейсов ?, то есть не внедрять их в начальном определении, но позже, возможно, в том же файле после того, как я внедрил модуль для типа. Я объясню с упрощенным пример: Предположим, у меня есть следующая структура данных:Задержка реализации методов интерфейса?

type 'T MyCollection = 
     (*type definition*) 
     interface IEnumerable<'T> with 
      member this.GetEnumerator() = 
       (* I don't want to implement it here 
        because I still don't have the module 
        with a toSeq function *) 

Если я реализовал метод прямо там, я должен был бы также выполнять все функции, методы типа и затем модуль будет просто «прокси» для вызова методов. Таким образом, я создаю структуру данных OO-first, а затем создаю модуль (перегруженный аннотациями типа), чтобы обеспечить функциональное использование. Я бы предпочел написать функционально-первую структуру данных (более чистую, так как вывод типа может работать лучше), а затем создать OO-оболочку, чтобы обеспечить лучшую поддержку intellisense для таких языков, как C#. Этот подход соответствует тому, что нам предлагает руководство по проектированию для F #, но интерфейсы не могут быть реализованы нигде, кроме первоначального определения типа. Это ограничение заставляет меня написать всю структуру данных с членами. Я искал примеры, и я обнаружил, что реализация списка в FSharp.Core list делает именно то, что я хочу, но я не могу этого сделать, компилятор мне не позволит. Я почти уверен, что это дизайнерское решение, возможно, чтобы не поощрять плохие практики, я не знаю, но я не считаю свое желание быть плохой практикой. Также я хорошо знаю линейную природу компилятора fsharp.

Пожалуйста, если кто-либо из вас знает, как делать то, что я хочу, я буду рад, если вы скажете мне. Кроме того, если кто-то из вас знает, почему я не должен следовать этому подходу, я тоже буду рад узнать. Должна быть причина, почему это не проблема для кого-либо еще.

Заранее спасибо.

ответ

9

Я полностью согласен с тем, что это неудачная проблема. Трюк, который используется в исходном коде 'a list в библиотеке ядра F #, заключается в определении реализации интерфейса в дополнении . Компилятор не жалуется, когда вы добавляете членов к типу таким образом, но он говорит, что добавление реализации интерфейса таким образом устарело. Однако это не мешает вам это делать. Ниже компилируется нормально для меня:

open System.Collections 
open System.Collections.Generic 

type MyCollection<'T> = 
    { Data : 'T list } 
    interface IEnumerable<'T> 
    interface IEnumerable 

let getEnumerator { Data = d } = 
    (d :> seq<_>).GetEnumerator() 

type MyCollection<'T> with 
    interface IEnumerable<'T> with 
    member this.GetEnumerator() = getEnumerator this 
    interface IEnumerable with 
    member this.GetEnumerator() = (getEnumerator this) :> _ 

Тот факт, что это осуждается немного неудачно. Мне очень нравится этот стиль, и я использую его, когда это имеет смысл. Вы можете start a discussion about this on F# user voice, и, возможно, его можно было бы вернуть обратно к нормальной принятой функции :-)

+0

Спасибо за ответ, мне было очень стыдно, что я мог ошибиться в своем понимании. До сих пор я рассматривал эту проблему по-своему, потому что весь мой код F # был для личного использования. Мне не приходилось предоставлять хороший интерфейс для языков OO. Но недавно я добавил реализацию SkewBinomialHeap в fsharpx.collections (все еще в запросе на растяжение) и должен был иметь дело с этим более традиционным и общедоступным способом. –

+0

Да, это решение работает отлично. Но я боюсь, что в будущей версии языка он может измениться с устаревшего на нелегальный. Еще раз спасибо. –

+0

[Голос пользователя] (http://fslang.uservoice.com/forums/245727-fanguage/suggestions/8733178-revert-back-to-an-accepted-feature-the-delayed-imp) –

Смежные вопросы