using System.Drawing;
namespace Scan
{
class Scanner
{
enum PixelColor {
| Black
| White
| EOFLine
| EOFFile
}
static GetNextPixel ( x:int, y:int, bmp:Bitmap) : int * int * Bitmap * PixelColor
{
when (x==bmp.Size.Width)
def _height=bmp.Height;
match (y){
|_height => (x, y, bmp, PixelColor.EOFFile)
| _ => (0, y+1, bmp, PixelColor.EOFLine)
}
when (bmp.GetPixel(x,y) == System.Drawing.Color.Black)
{(x+1, y, bmp, PixelColor.Black)}
(x+1, y, bmp, PixelColor.White)
}
static Parse(filePath:string):void
{
def bmp=Bitmap(filePath, false);
_=GetNextPixel(0, 0, bmp);
}
static Main() : void
{
_=Parse("barcode.bmp")
}
}
}
дает следующие ворнинги:
>C:\Program Files\Nemerle\ncc.exe -no-color -r System.Windows.Forms -r System.Data -t exe scan.n -o scan.exe
scan.n:19:1:19:6: warning: N10005: ignored computed value of type (int * int * System.Drawing.Bitmap * Scan.Scanner.PixelColor)
scan.n:19:1:19:6: hint: use `_ = ...'; or -nowarn:10005 to avoid the warning
scan.n:24:2:24:33: warning: N10005: ignored computed value of type (int * int * System.Drawing.Bitmap * Scan.Scanner.PixelColor)
scan.n:21:3:21:4: warning: this match clause is unused
>Exit code: 0
GZ>дает следующие ворнинги: GZ>scan.n:19:1:19:6: warning: N10005: ignored computed value of type (int * int * System.Drawing.Bitmap * Scan.Scanner.PixelColor)
match — выражение, (**) возвращает значение, которое ты никуда не сохраняешь. Кстати, толи у тебя форматирование съехало, толи ты забыл после when (x==bmp.Size.Width) поставить '{' ну и соответсвенно потом '}'.
GZ>scan.n:19:1:19:6: hint: use `_ = ...'; or -nowarn:10005 to avoid the warning GZ>scan.n:24:2:24:33: warning: N10005: ignored computed value of type (int * int * System.Drawing.Bitmap * Scan.Scanner.PixelColor)
(++) — аналогично, не сохраняешь значение. Компилятором ожидается что-то вроде:
when (bmp.GetPixel(x,y) == System.Drawing.Color.Black)
_ = (x+1, y, bmp, PixelColor.Black);
И зачем тут {}?
GZ>scan.n:21:3:21:4: warning: this match clause is unused
А тут видимо ты не совсем представляешь себе как в Немерле работает сопоставление с образцом.
def _height=bmp.Height;
match (y){
| _height => // это сопоставление выполнится всегда, тут в _height запишут значение y
(x, y, bmp, PixelColor.EOFFile)
| _ => (0, y+1, bmp, PixelColor.EOFLine)
}
Так что надо как-то так:
def _height=bmp.Height;
match (y){
| _ when y == _height => (x, y, bmp, PixelColor.EOFFile)
| _ => (0, y+1, bmp, PixelColor.EOFLine)
}
Да и match тут вообщем-то не нужен:
def _height=bmp.Height;
if (y == _height)
(x, y, bmp, PixelColor.EOFFile)
else
(0, y+1, bmp, PixelColor.EOFLine)
Здравствуйте, GlebZ, Вы писали:
GZ>Не понял о чем ворнинги?
Для начала посоветовал бы более качествнно отбивать код. А то читать очень трудно.
Теперь по делу. Вот грамотно отформатированный код с описанием ошибок:
when (x==bmp.Size.Width)
def _height = bmp.Height; // эта переменная будет видна только в пределах when (вообще странно что этот код компилируется).
match (y) // этот match возвращает значения (кортежи), так что любой код после него никогда не будет исполнен.
{
|_height => (x, y, bmp, PixelColor.EOFFile) // этот паттерн перекрывает все возможные варианты! _height - это не переменная объявленная раньше, а переменная связанная в паттерне
| _ => (0, y+1, bmp, PixelColor.EOFLine) // этот код никогда не выполнится.
}
when (bmp.GetPixel(x,y) == System.Drawing.Color.Black) // этот код не может работать.
(x+1, y, bmp, PixelColor.Black)
Явно море ошибок.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, ie, Вы писали:
ie>match — выражение, (**) возвращает значение, которое ты никуда не сохраняешь.
Результат должен возвращать кортеж из функции.
ie>(++) — аналогично, не сохраняешь значение. Компилятором ожидается что-то вроде: ie>
ie> when (bmp.GetPixel(x,y) == System.Drawing.Color.Black)
ie> _ = (x+1, y, bmp, PixelColor.Black);
ie>
ie>И зачем тут {}?
Убираешь — получаешь ошибку.
scan.n:26:1:26:28: error: the value called (((+.s (x, 1) :> int-), (y :> int-), ((0 :> Scan.Scanner.PixelColor) :> Scan.Scanner.PixelColor-))) has non-functional type (int- * int- * Scan.Scanner.PixelColor-)
scan.n:25:1:25:5: error: expected ?, got void in computation branch
ie>А тут видимо ты не совсем представляешь себе как в Немерле работает сопоставление с образцом.
Похоже да. ie>Так что надо как-то так: ie>
ie> def _height=bmp.Height;
ie> match (y){
ie> | _ when y == _height => (x, y, bmp, PixelColor.EOFFile)
ie> | _ => (0, y+1, bmp, PixelColor.EOFLine)
ie> }
ie>
То есть — если у нас в условии константа, то он сравнивает. А если переменная, то уже идет присвоение?????????
ie>Да и match тут вообщем-то не нужен:
Пока интересует именно match.
Здравствуйте, VladD2, Вы писали:
VD>Здравствуйте, GlebZ, Вы писали:
GZ>>Не понял о чем ворнинги?
VD>Для начала посоветовал бы более качествнно отбивать код. А то читать очень трудно. VD>Теперь по делу. Вот грамотно отформатированный код с описанием ошибок: VD>[c#] VD>when (x==bmp.Size.Width) VD> def _height = bmp.Height; // эта переменная будет видна только в пределах when (вообще странно что этот код компилируется).
Там скобки убрал после метода случайного тыка. Случайно послал неверный код. Должно быть —
when(x==bmp.Size.Width){
def ...;
.....
}
VD>when (bmp.GetPixel(x,y) == System.Drawing.Color.Black) // этот код не может работать. VD> (x+1, y, bmp, PixelColor.Black)
Почему?
VD>Явно море ошибок.
Иначе бы не писал месагу
Здравствуйте, GlebZ, Вы писали:
ie>>match — выражение, (**) возвращает значение, которое ты никуда не сохраняешь. GZ>Результат должен возвращать кортеж из функции.
when — statement, он ничего не возвращает.
ie>>(++) — аналогично, не сохраняешь значение. Компилятором ожидается что-то вроде: ie>>
ie>> when (bmp.GetPixel(x,y) == System.Drawing.Color.Black)
ie>> _ = (x+1, y, bmp, PixelColor.Black);
ie>>
ie>>И зачем тут {}? GZ>Убираешь — получаешь ошибку. GZ>
GZ>scan.n:26:1:26:28: error: the value called (((+.s (x, 1) :> int-), (y :> int-), ((0 :> Scan.Scanner.PixelColor) :> Scan.Scanner.PixelColor-))) has non-functional type (int- * int- * Scan.Scanner.PixelColor-)
GZ>scan.n:25:1:25:5: error: expected ?, got void in computation branch
Прикольно. Тут так получается:
when (bmp.GetPixel(x,y) == System.Drawing.Color.Black)
(x+1, y, bmp, PixelColor.Black)(x+1, y, bmp, PixelColor.White)
т.е. компилятор ожидает, что выделенное будет функцией принимеющей кортеж и чета возвращающей, а там какая-то фигня.
ie>>А тут видимо ты не совсем представляешь себе как в Немерле работает сопоставление с образцом. GZ>Похоже да. ie>>Так что надо как-то так: ie>>
ie>> def _height=bmp.Height;
ie>> match (y){
ie>> | _ when y == _height => (x, y, bmp, PixelColor.EOFFile)
ie>> | _ => (0, y+1, bmp, PixelColor.EOFLine)
ie>> }
ie>>
GZ>То есть — если у нас в условии константа, то он сравнивает. А если переменная, то уже идет присвоение?????????
Да, происходит связывание.
GZ>ЗЫ. А что значит минус в типе int-?
Ко/контр-вариантность.
def f(g, x : A) : B
{
g(x);
}
g должна иметь тип: (A-) : B+, т.е. принимать A или его предков и возвращать B или его наследников, что бы не нарушать контракт A
Здравствуйте, GlebZ, Вы писали:
VD>>when (bmp.GetPixel(x,y) == System.Drawing.Color.Black) // этот код не может работать. VD>> (x+1, y, bmp, PixelColor.Black) GZ>Почему?
На самом деле я немного не прав. Тот фат что match возвращает значение еще не делает его возвращаемым значением метода. Так что реакция будет дрдугая. Значение вознвращенное match-ем просто будет проигнорировано (о чем и предупреждает компилятор), а данная строка конечно выполнится, но все равно это явная ошибка.
Вообще, предупреждения ncc лучше не игнорировать. Там очень много пракрически ошибок интерпретирубтся как предупреждения.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, GlebZ, Вы писали:
GZ>Путем перчитки документации — все прояснилось. Императив без return здесь не пройдет. Единственный вопрос — что за хрень int-. Что обозначает минус?
Как я понимаю это дополнительное описание к типу. "+" вроде бы означает, что может быть этот тип и шире, а "-" этот или уже (или просто точно этот).
Лучше спросить у компиляторщиков.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, GlebZ, Вы писали:
GZ>Уже переписал как : GZ>
GZ>GetNextPixel1 ( x:int, y:int, bmp:Bitmap) : int * int * PixelColor {
GZ> | _ when (x == bmp.Size.Width) =>
GZ> if (y== bmp.Size.Height) (x, y, PixelColor.EOFFile)
GZ> else (x, y, PixelColor.EOFLine)
GZ> | _ when (bmp.GetPixel(x, y) == System.Drawing.Color.Black) => (x+1, y, PixelColor.Black)
GZ> | _ => (x+1, y, PixelColor.White)
GZ>}
GZ>
А какой смысл тут в паттерн-мачинге? Только код более медленный получится.
GetNextPixel1(x : int, y : int, bmp : Bitmap) : int * int * PixelColor
{
if (x == bmp.Size.Width)
if (y == bmp.Size.Height) (x, y, PixelColor.EOFFile)
else (x, y, PixelColor.EOFLine)
else if (bmp.GetPixel(x, y) == System.Drawing.Color.Black)
(x + 1, y, PixelColor.Black)
else (x + 1, y, PixelColor.White)
}
А вообще, если хочешь покрасивее это дело оформить и нужен толтько перебор, то лучше всего просто сделать итератор с помощью yield.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Подумав немного еще пришел к выводу, что ты похоже недопонмаешь приципа ветвления.
Ни одни оператор в Nemerle кроме return (который нужн отдельно импортировать) не может ни прирвать выполнение метода, ни изменить хода вычислений. Ты можешь только задать ветвление.
when позволяет тебе выполнить некоторое действие по условию. Но это действие привдет к возврату из фукнции только если ты завершил его return-ом.
if/else возвращает значение if- или else-части.
match возвращает значение сработавшего вхождения.
В общем, стркутура метода при использовании встроенных средств Nemerle сильно отличается от того что ты привык видеть в C# и себя нужно немного приучить, что есть только ветвление, а не возвраты и выполнение опрераторов.
Если же хочешь видеть аля C#-ый код, то импортиру пространство имен Nemerle.Imperative и пользуйся return-ами и break-ами.
По мне так после некоторого привыкания без return-ов получается жить лучше. Код становится проще читать (его можно читать просто сверху вниз). Все становится предстазуемее.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, VladD2, Вы писали:
VD>А какой смысл тут в паттерн-мачинге? Только код более медленный получится.
Медленнее вряд ли. Я посмотрел через рефлектор. А вот более читабельным — будет. К тому же набор условий будет меняться. Паттерн-мачинг в таких вещах более предпочтительный.
VD>А вообще, если хочешь покрасивее это дело оформить и нужен толтько перебор, то лучше всего просто сделать итератор с помощью yield.
В данном конкретном случае — это излишне.
Здравствуйте, VladD2, Вы писали:
VD>В общем, стркутура метода при использовании встроенных средств Nemerle сильно отличается от того что ты привык видеть в C# и себя нужно немного приучить, что есть только ветвление, а не возвраты и выполнение опрераторов.
Я просто недавно практиковался в Хаскеле, где для последовательного выполнения функций нужно либо играться с point либо монадами. Мне как старому императивщику трудно к этому привыкнуть. Здесь же все просто. Ну меня и понесло. Захотел больше императива в функц. языке, чем можно себе позволить.
VD>По мне так после некоторого привыкания без return-ов получается жить лучше. Код становится проще читать (его можно читать просто сверху вниз). Все становится предстазуемее.
+1
Здравствуйте, GlebZ, Вы писали:
GZ>Я просто недавно практиковался в Хаскеле, где для последовательного выполнения функций нужно либо играться с point либо монадами. Мне как старому императивщику трудно к этому привыкнуть. Здесь же все просто. Ну меня и понесло. Захотел больше императива в функц. языке, чем можно себе позволить.
Хочешь — имей. Но тогда уж импортируй Nemerle.Imperative и используй return. Откровенно говоря в этом твоем примере это совершенно лишнее, но иногда это очень удобно. Например, когда алгоритм видится как поиск перебором с прерыванием поиска при нахождении элемента.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.