Следующий код не компилируется в ревизии 8400:
using System;
using System.Console;
using Nemerle.Utility;
module Program
{
Main() : void
{
def l = [1, 2, 3];
def r = match(l)
{
| _ :: 2 :: _ => "cool"
| [] => "empty one"
}
WriteLine(r);
}
}
D:\2008.12.11\ConsoleApplication8\ConsoleApplication8\Main.n(13,9):Error: the matched value type list[int] was expected to be compatible with list[?]: Nemerle.Core.Nil[T].[T] is not a subtype of Nemerle.Core.Cons[T].[T] [simple require]
... << RSDN@Home 1.2.0 alpha 4 rev. 1250>>
Здравствуйте, Clerk, Вы писали:
C>Следующий код не компилируется в ревизии 8400:
C>using System;
[skip]
C> def l = [1, 2, 3];
C> def r = match(l)
C> {
C> | _ :: 2 :: _ => "cool"
C> | [] => "empty one"
C> }
[skip]
C>}
C>D:\2008.12.11\ConsoleApplication8\ConsoleApplication8\Main.n(13,9):Error: the matched value type list[int] was expected to be compatible with list[?]: Nemerle.Core.Nil[T].[T] is not a subtype of Nemerle.Core.Cons[T].[T] [simple require]
Корявое сообщение об ошибке — баг, но содержание его в принципе "правильное":
известно, что тип l — list[int].Cons — непустой список, а тип [] — list[?].Nil — пустой список, не сматчатся по типу.
Здравствуйте, Иванков Дмитрий, Вы писали:
ИД>Корявое сообщение об ошибке — баг, но содержание его в принципе "правильное":
ИД>известно, что тип l — list[int].Cons — непустой список, а тип [] — list[?].Nil — пустой список, не сматчатся по типу.
Как же тогда проверит на пустой список?
... << RSDN@Home 1.2.0 alpha 4 rev. 1250>>
Здравствуйте, Clerk, Вы писали:
C>Как же тогда проверит на пустой список?
def r = match(l)
{
| _ :: 2 :: _ => "cool"
| _ => "empty one"
}
Так попробуй...
Вывод типов позволяет сразу определить, что вариант
match с пустым списком не подходит в этом случае. Такое, к примеру, работает как надо:
def f(l)
{
| _ :: 2 :: _ => "cool"
| [] => "empty one"
| _ => "something else"
}
[ [1, 2, 3]
, []
, [0, 1]
].Map(f).Iter(System.Console.WriteLine);
Здравствуйте, Clerk, Вы писали:
C>Здравствуйте, Иванков Дмитрий, Вы писали:
ИД>>Корявое сообщение об ошибке — баг, но содержание его в принципе "правильное":
ИД>>известно, что тип l — list[int].Cons — непустой список, а тип [] — list[?].Nil — пустой список, не сматчатся по типу.
C>Как же тогда проверит на пустой список?
Дело не в проверке на пустоту списка. Дело в типе параметра матча.
Так как ты задал тип списка не явно, то он вывелся как list[int].Cons(), а тип [] — это list[int].Nil(). Так как list[int].Cons() нельзя привести к list[int].Nil(), возникает сообщение об ошибке. Тут требуется где-то уточнить тип. Например, так:
def lst : list[int] = [1, 2, 3];
или даже так:
def lst : list[_] = [1, 2, 3];
Уточнить можно и в любом другом месте. Например, так:
def lst = [1, 2, 3];
def r = match(lst)
{
//| _ :: 2 :: _ => "cool"
| _ :: _ => ""
| [] : list[_] => "empty one"
};
ЗЫ
На саомо деле причина появления такого странного сообщения в том, что ты пишешь какие-то тесыт. В реальном коде такое не встречается. Бессмысленно объявлять конкретный тип списка и тут же его проверять. А когда ты будешь иметь ссылку на список, то проблемы не возникнет.
Тем не мнее имеет смысл улучшить собщение об ошибке. Так что хорошо бы добавить запрос на это в баг-трекер.