Это зависит от оператора.
точка создания виртуального оператора присваивания должна позволить Вам от преимущества способности переопределить его для копирования большего количества полей.
Поэтому, если у Вас есть Base& и у Вас на самом деле есть Derived& как динамический тип и Полученный имеет больше полей, корректные вещи копируются.
Однако существует тогда риск, что Ваш LHS является Полученным, и RHS является Основа, поэтому когда выполнения виртуального оператора в Полученном, Ваш параметр не является Полученным и у Вас нет способа вытащить поля из него.
Вот хороший discussio: http://icu-project.org/docs/papers/cpp_report/the_assignment_operator_revisited.html
Одной из ключевых особенностей модулей ML является совместное использование спецификаций. В .NET нет механизма, который мог бы их имитировать - требуемые механизмы слишком разные.
Вы можете попытаться сделать это, превратив общие типы в параметры, но это не может точно имитировать способность определять подпись, а затем применить к ней совместное использование, возможно, несколькими различными способами.
На мой взгляд, .NET выиграет от чего-то, что действительно имеет такой механизм - тогда он приблизится к реальной поддержке разнообразия современных языков. Надеюсь, включить более свежие достижения в модульных системах, таких как MixML, что, на мой взгляд, является будущим модульных систем. http://www.mpi-sws.org/~rossberg/mixml/
Я недостаточно хорошо знаю функторы ML, чтобы действительно ответить на ваш вопрос. Но я скажу, что единственный ограничивающий фактор .Net, который я всегда нахожу в монадическом программировании, - это неспособность абстрагироваться от 'M' в смысле «для всех M. некоторого выражения типа с M
Комментарий Брайана уместен. Вот код OCaml, который использует функторы для предоставления (строгой) реализации Haskell sequence :: (Monad m) => [ma] -> m [a]
, параметризованной для рассматриваемой монады:
module type Monad =
sig
type 'a t (*'*)
val map : ('a -> 'b) -> ('a t -> 'b t)
val return : 'a -> 'a t
val bind : 'a t -> ('a -> 'b t) -> 'b t
end
module type MonadUtils =
sig
type 'a t (*'*)
val sequence : ('a t) list -> ('a list) t
end
module MakeMonad (M : Monad) : MonadUtils =
struct
type 'a t = 'a M.t
let rec sequence = function
| [] ->
M.return []
| x :: xs ->
let f x =
M.map (fun xs -> x :: xs) (sequence xs)
in
M.bind x f
end
Это выглядит сложным для выражения в .NET.
ОБНОВЛЕНИЕ :
Используя метод naasking
, я смог закодировать повторно используемую функцию последовательности
в F # в в основном типобезопасный способ (использует понижающие значения).
HigherLogics - это мой блог, и я потратил много времени на изучение этого вопроса. Ограничением действительно является абстракция по отношению к конструкторам типов, также известная как «универсальные типы над универсальными». Кажется, лучшее, что вы можете сделать для имитации модулей и функторов ML, требует как минимум одного (полубезопасного) приведения.
В основном это сводится к определению абстрактного типа и интерфейса, который соответствует сигнатуре модуля, который работает с ним. тип. Абстрактный тип и интерфейс имеют общий параметр типа B, который я называю «брендом»; бренд - это обычно просто подтип, реализующий интерфейс модуля. Бренд гарантирует, что переданный тип является правильным подтипом, ожидаемым модулем.
// signature
abstract class Exp<T, B> where B : ISymantics<B> { }
interface ISymantics<B> where B : ISymantics<B>
{
Exp<int, B> Int(int i);
Exp<int, B> Add(Exp<int, B> left, Exp<int, B> right);
}
// implementation
sealed class InterpreterExp<T> : Exp<T, Interpreter>
{
internal T value;
}
sealed class Interpreter : ISymantics<Interpreter>
{
Exp<int, Interpreter> Int(int i) { return new InterpreterExp<int> { value = i }; }
Exp<int, Interpreter> Add(Exp<int, Interpreter> left, Exp<int, Interpreter> right)
{
var l = left as InterpreterExp<int>; //semi-safe cast
var r = right as InterpreterExp<int>;//semi-safe cast
return new InterpreterExp<int> { value = l.value + r.value; }; }
}
}
Как видите, приведение в основном безопасно, поскольку система типов гарантирует, что марка типа выражения соответствует марке интерпретатора. Единственный способ облажаться, если клиент создаст свой собственный класс Exp и укажет марку Interpreter. Существует более безопасная кодировка, которая позволяет избежать этой проблемы, но она слишком громоздка для обычного программирования.
Позже я использовал эту кодировку и перевел примеры из одной из статей Олега, написанных на MetaOCaml, на использование C #. и Linq. Интерпретатор может прозрачно запускать программы, написанные с использованием этого встроенного языка, на стороне сервера в ASP.NET или на стороне клиента как JavaScript.
Эта абстракция над интерпретаторами - особенность окончательного кодирования Олега без тегов. Ссылки на его статью приведены в сообщении блога.
Интерфейсы являются первоклассными в .NET, и, поскольку мы используем интерфейсы для кодирования подписей модулей, модули и подписи модулей также являются первоклассными в этой кодировке. Таким образом, функторы просто используют интерфейс непосредственно вместо сигнатур модулей, т.е. они будут принимать экземпляр ISymantics и делегировать ему любые вызовы.
I've now posted a detailed description of my translation for ML modules, signatures and functors to an equivalent C# encoding. I hope someone finds it useful.