не хочет применяться оператор
От: AngeL B. Россия  
Дата: 12.06.07 10:12
Оценка:
Написал код

using System;
using System.Console;

type period = DateTime * DateTime;

public module DateHelper {
    public @* ( a : period, b : period ) : period
    {
            def max_start =
                if( a[0] > b[0] ) a[0]; else b[0];

            def min_stop =
                if( a[1] < b[1] ) a[1]; else b[1];
                
            (max_start, min_stop);
    }
}

def a = (DateTime.Now, DateTime.Now.AddDays(2));
def b = (DateTime.Now.AddDays(-3), DateTime.Now.AddDays(1));

WriteLine( a * b );


при компиляции говорит

a.n:23:12:23:17: error: typing fails on operator `op_Multiply' on (System.DateTime- * System.DateTime-
) and (System.DateTime- * System.DateTime-)

приходиться писать алгоритмы (много) вычислений оперируя интервалами дат. Хотел попробовать облегчить себе задачу
я не могу что-то сказать в чем дело . Помогите...
Re: не хочет применяться оператор
От: AngeL B. Россия  
Дата: 12.06.07 10:49
Оценка:
Здравствуйте, AngeL B., Вы писали:

Всё, вопрос решен (пока что).

надо было написать

using DateHelper;
Re: не хочет применяться оператор
От: AngeL B. Россия  
Дата: 12.06.07 11:39
Оценка:
Кстати говоря, при решении этого вопроса выплыл ещё однин момент.
У меня в модуле DateHelper есть оператор вида

public @+( date : DateTime, delta : double ) : DateTime {...}


прибувляющий к дате по дням (.AddDays).

Так вот в следующем коде компилятор не смог разобраться с выведением типа, заблудившись всего в двух операторах
+(DateTime, double) и +(double, double).

public Sum( this protocol : list[ProtocolItem], predicate : ProtocolItem -> bool ) : double
        {
            def summator(pi, sum) {
                if( predicate(pi) ) {
                    if( pi.Article.IsAdditional )
                        sum + pi.Sum;
                    else
                        sum - pi.Sum;
                }
                else sum;
            }
            
            protocol.FoldLeft(0.00 : double, summator); //134 строка
        }


в строке А он сказал

CalcHelpers.n:134:13:134:30: error: overload #2, method Nemerle.Core.list.FoldLeft(acc : 'b.672, f : (
'a.7 * 'b.672) -> 'b.672) : 'b.672
CalcHelpers.n:134:13:134:30: error: in argument #2 (f) of protocol.FoldLeft.[(System.DateTime TILL Sys
tem.Double)], needed a (DSTU.Wages.Objects.ProtocolItem * System.Double-) -> System.Double-, got (DSTU
.Wages.Objects.ProtocolItem+ * System.DateTime+) -> System.DateTime-: the types (DSTU.Wages.Objects.Pr
otocolItem * (System.DateTime TILL System.Double)) and (DSTU.Wages.Objects.ProtocolItem+ * (System.Dat
eTime TILL System.Double)) are not compatible [simple unify]

что странно, так как по условию описания FoldLeft тип первого параметра (самого FoldLeft) и второго параметра лямбды (которая второй парметр FoldLeft) должны совпадать.
А первый параметр FoldLeft однозначно указан как double, но уж никак не DateTime.
Почему в этом случае компилятор не вывел что параметр sum сумматора тоже double?
Это недоработка или я тут пропускаю некую тонкость при выведении типов, которая может привести к ошибкам?
Re[2]: не хочет применяться оператор
От: Иванков Дмитрий Россия  
Дата: 12.06.07 13:15
Оценка: +1
Здравствуйте, AngeL B., Вы писали:

AB>Так вот в следующем коде компилятор не смог разобраться с выведением типа, заблудившись всего в двух операторах

AB>+(DateTime, double) и +(double, double).

Если правильно понимаю, то в коде используется +(double, DateTime)
Если это не так, то просьба привести самодостаточный и в то же время краткий код, воспроизводящий ошибку.
Re[2]: не хочет применяться оператор
От: Иванков Дмитрий Россия  
Дата: 12.06.07 13:39
Оценка:
Здравствуйте, AngeL B., Вы писали:

AB>Так вот в следующем коде компилятор не смог разобраться с выведением типа, заблудившись всего в двух операторах

AB>+(DateTime, double) и +(double, double).

Вот еще что, если есть подозрения что виноват вывод типов, то можно типы проставить и посмотреть что станет с ошибками.
Re[2]: не хочет применяться оператор
От: VladD2 Российская Империя www.nemerle.org
Дата: 12.06.07 13:48
Оценка:
Здравствуйте, AngeL B., Вы писали:

AB>Всё, вопрос решен (пока что).

AB>надо было написать
AB>using DateHelper;

Откровенно говоря C# не позволяет пергружать операторы для уже существующих типов. Одни из типов при перегрузке должен быть текущим.

Незнаю намеренно ли этот запрет обойден в Немерле. Так что не факт, что данное поведение вообще корректно. В прочем, это было бы очень удобно. Мне всегда было не понятно, почему в С++ я могу перегрузить операторы для любых типов, а в Шарпе только для своих.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re: не хочет применяться оператор
От: VladD2 Российская Империя www.nemerle.org
Дата: 12.06.07 13:48
Оценка:
Здравствуйте, AngeL B., Вы писали:

Кстати, для хранения дельты времени в дотнете предусмотрен тип TimeSpan(). Ты случаем не изобретаешь велосипед?
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[3]: не хочет применяться оператор
От: VladD2 Российская Империя www.nemerle.org
Дата: 12.06.07 13:57
Оценка:
Здравствуйте, Иванков Дмитрий, Вы писали:

ИД>Если правильно понимаю, то в коде используется +(double, DateTime)

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

Проверил... ты абсолютно прав. Так и есть. Вот такой тест работает:
using System;
using System.Console;
using Overl; // This is expected behavior?

public module Overl
{
  public @+(date : DateTime, delta : long) : DateTime // This is expected behavior?
  {
    date + TimeSpan(delta)
  }

  public @+(delta : long, date : DateTime) : DateTime // This is expected behavior?
  {
    date + TimeSpan(delta)
  }
}

module Program
{
  Main() : void
  {
    def now = DateTime.Now;
    WriteLine(now);
    WriteLine(now + 20000000L);
    WriteLine(20000000L + now);
    _ = ReadLine();
  }
}

Если закоментировать в нем один вариант перегрузки оператора, то выдается сообщение об ошибке.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[3]: не хочет применяться оператор
От: AngeL B. Россия  
Дата: 12.06.07 14:21
Оценка: 8 (1)
Здравствуйте, Иванков Дмитрий, Вы писали:

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


Самодостаточный код, воспроизводящий ошибку.
Если явно затипизировать параметр sum функции summator как double, ошибка исчезает.
Но как я уже писал, второй параметр лямбды в FoldLeft обязан совпадать по типу с первым параметров FoldLeft. И следовательно, если исходить из принципа, что тип определяется из использования, параметр sum явно должен быть double. Но вместо этого компилятор выводит его тип как DateTime (даже не могу понять откуда). Это видно из текста ошибки ниже кода.

using System;
using System.Console;
using DateHelper;

public module DateHelper 
{
    public @+( date : DateTime, delta : double ) : DateTime
    {
        date.AddDays(delta);
    }
    
    public @-( date : DateTime, delta : double ) : DateTime
    {
        date.AddDays(-delta);
    }
}

def rand = Random();

def summator(x, sum)
{
    if( rand.Next(100) > 50 ) sum + x; else sum - x;
}

def l = $[0.0, 0.5 .. 5];
WriteLine( l.FoldLeft(0.00 : double, summator) );


a.n:27:12:27:47: error: in argument #2 (f) of l.FoldLeft.[(System.DateTime TILL System.Double)], neede
d a (System.Double- * System.Double-) -> System.Double-, got (System.Double+ * System.DateTime+) -> Sy
stem.DateTime-
: the types (System.Double- * (System.DateTime TILL System.Double)) and (System.Double+
* (System.DateTime TILL System.Double)) are not compatible [simple unify]
Re[4]: не хочет применяться оператор
От: AngeL B. Россия  
Дата: 12.06.07 14:30
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Если закоментировать в нем один вариант перегрузки оператора, то выдается сообщение об ошибке.


ух ты жесть. То есть товарищи предполагают, что от перемены мест слагаемых может поменяться результат?
Re[4]: не хочет применяться оператор
От: Mckey Россия  
Дата: 12.06.07 14:32
Оценка:
Здравствуйте, AngeL B., Вы писали:

AB>Здравствуйте, Иванков Дмитрий, Вы писали:


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


AB>Самодостаточный код, воспроизводящий ошибку.

AB>Если явно затипизировать параметр sum функции summator как double, ошибка исчезает.
AB>Но как я уже писал, второй параметр лямбды в FoldLeft обязан совпадать по типу с первым параметров FoldLeft. И следовательно, если исходить из принципа, что тип определяется из использования, параметр sum явно должен быть double. Но вместо этого компилятор выводит его тип как DateTime (даже не могу понять откуда). Это видно из текста ошибки ниже кода.

AB>
AB>using System;
AB>using System.Console;
AB>using DateHelper;

AB>public module DateHelper 
AB>{
AB>    public @+( date : DateTime, delta : double ) : DateTime
AB>    {
AB>        date.AddDays(delta);
AB>    }
    
AB>    public @-( date : DateTime, delta : double ) : DateTime
AB>    {
AB>        date.AddDays(-delta);
AB>    }
AB>}

AB>def rand = Random();

AB>def summator(x, sum)
AB>{
AB>    if( rand.Next(100) > 50 ) sum + x; else sum - x;
AB>}

AB>def l = $[0.0, 0.5 .. 5];
AB>WriteLine( l.FoldLeft(0.00 : double, summator) );
AB>


AB>a.n:27:12:27:47: error: in argument #2 (f) of l.FoldLeft.[(System.DateTime TILL System.Double)], neede

AB>d a (System.Double- * System.Double-) -> System.Double-, got (System.Double+ * System.DateTime+) -> Sy
AB>stem.DateTime-
: the types (System.Double- * (System.DateTime TILL System.Double)) and (System.Double+
AB>* (System.DateTime TILL System.Double)) are not compatible [simple unify]

Может исходя из того что ты сделал using DataHelper?

Уже много раз проверял на своем опыте что для предопределенных типов перегрузки операций не даются...
Если сделать юсинг класса где определены операции, то вылазиют другие ошибки...
Единственно еще можно попробовать определить операции в namespace Nemerle в module Core...
Насколько я знаю — эту возможность пока не убрали — это нечто вроде хака...

Помню кто-то раньше предлагал:

namespace Nemerle
{
    public module Core
    {
        public static @$[A,B,C](this fbc : B->C, fab : A->B) : A->C
        {
            match(fab : object)
            {
                | fa is void->B => ((() => fbc(fa())) : object) :> A->C
                | _ => a => fbc(fab(a))
            }
        }
    }
}
Делай добро и бросай его в воду...
Re[2]: не хочет применяться оператор
От: AngeL B. Россия  
Дата: 12.06.07 14:36
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Кстати, для хранения дельты времени в дотнете предусмотрен тип TimeSpan(). Ты случаем не изобретаешь велосипед?


Нет. Есть команда пишущая на Delphi, а там тип TDateTime = double где целая единица = одному дню.
Если мы решимся переписать расчетные алгоритмы на Nemerle, то программистам (простым) будет легче, если типы будут вести себя похоже.
Re[4]: не хочет применяться оператор
От: VladD2 Российская Империя www.nemerle.org
Дата: 12.06.07 14:41
Оценка:
Здравствуйте, AngeL B., Вы писали:

AB>
AB>using System;
AB>using System.Console;
AB>using DateHelper;

AB>public module DateHelper 
AB>{
AB>    public @+( date : DateTime, delta : double ) : DateTime
AB>    {
AB>        date.AddDays(delta);
AB>    }
    
AB>    public @-( date : DateTime, delta : double ) : DateTime
AB>    {
AB>        date.AddDays(-delta);
AB>    }
AB>}

AB>def rand = Random();

AB>def summator(x, sum)
AB>{
AB>    if( rand.Next(100) > 50 ) sum + x; else sum - x;
AB>}

AB>def l = $[0.0, 0.5 .. 5];
AB>WriteLine( l.FoldLeft(0.00 : double, summator) );
AB>


Ничего не понимаю. А зачем в этом примере операторы сложения DateTime и double если они нигде не используются?
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[5]: не хочет применяться оператор
От: VladD2 Российская Империя www.nemerle.org
Дата: 12.06.07 14:45
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Ничего не понимаю. А зачем в этом примере операторы сложения DateTime и double если они нигде не используются?


Или это как раз и сбивает с толку компилятор?
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[5]: не хочет применяться оператор
От: VladD2 Российская Империя www.nemerle.org
Дата: 12.06.07 14:45
Оценка:
Здравствуйте, AngeL B., Вы писали:

AB>ух ты жесть. То есть товарищи предполагают, что от перемены мест слагаемых может поменяться результат?


1. Я не знаю корректно ли это поведение.
2. Я не знаю как в таких случаях дела обстаят в Шарпе (он вообще такой пример не скомпилирует).
3. В С++ (если не ошибаюсь) именно так и от переменны мест слагаемых влегкую может измениться все что угодно.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[3]: не хочет применяться оператор
От: VladD2 Российская Империя www.nemerle.org
Дата: 12.06.07 14:45
Оценка:
Здравствуйте, AngeL B., Вы писали:

AB>Нет. Есть команда пишущая на Delphi, а там тип TDateTime = double где целая единица = одному дню.

AB>Если мы решимся переписать расчетные алгоритмы на Nemerle, то программистам (простым) будет легче, если типы будут вести себя похоже.

Ясно.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[4]: не хочет применяться оператор
От: Иванков Дмитрий Россия  
Дата: 12.06.07 14:55
Оценка:
Здравствуйте, AngeL B., Вы писали:

AB>Самодостаточный код, воспроизводящий ошибку.

[skipped]

Спасибо, действительно баг.
Еще ужал и зарепортил, bug1026.
Re[3]: не хочет применяться оператор
От: IO Украина  
Дата: 12.06.07 18:31
Оценка:
Здравствуйте, Иванков Дмитрий, Вы писали:

ИД>Вот еще что, если есть подозрения что виноват вывод типов, то можно типы проставить и посмотреть что станет с ошибками.


Меня тут мучает вопрос. Допустим мы пишем консольную прогу. Есть пара функций. Есть стартовая точка Main() и использование функций. Мы в этих функциях не особо проставляем типы — компилятор их выводит из использования в Main(). Потом мы решаем вынести эти функции в отдельную сборку. Упс, эта сборка не компилируется — нету на основании чего вывести типы. Вывод — в библиотеках надо чаще явно вставлять типы. Или только в публичных функциях. Я прав?
Re[4]: не хочет применяться оператор
От: Иванков Дмитрий Россия  
Дата: 12.06.07 19:28
Оценка: +1
Здравствуйте, IO, Вы писали:


IO>Меня тут мучает вопрос. Допустим мы пишем консольную прогу. Есть пара функций. Есть стартовая точка Main() и использование функций. Мы в этих функциях не особо проставляем типы — компилятор их выводит из использования в Main(). Потом мы решаем вынести эти функции в отдельную сборку. Упс, эта сборка не компилируется — нету на основании чего вывести типы. Вывод — в библиотеках надо чаще явно вставлять типы. Или только в публичных функциях. Я прав?


Типы параметров и возвращаемого значения методов всегда надо указывать. (с небольшой поправкой: тип параметра может быть выведен из значения по умолчанию)
Если их не указать, то получим нечто вроде "вывод типов для сигнатур методов не поддерживается".
Так что описанных проблем быть не может, вывод типов работает только на локальных функциях и переменных.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.