- 01
- 02
- 03
- 04
- 05
- 06
- 07
- 08
- 09
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
/**
* Determines equality based upon the contents of this Box instead of the box itself.
* As a result, it is not symmetric. Which means that for
*
* <pre name="code" class="scala">
* val foo = "foo"
* val boxedFoo = Full(foo)
* foo == boxedFoo //is false
* boxedFoo == foo //is true
* </pre>
*
* For Full and Empty, this has the expected behavior. Equality in terms of Failure
* checks for equivalence of failure causes.
*/
override def equals(other: Any): Boolean = (this, other) match {
case (Full(x), Full(y)) => x == y
case (Full(x), y) => x == y
case (x, y: AnyRef) => x eq y
case _ => false
}
Full - лифтовый Box
За исключением val (что не суть), очень похоже на Nemerle. Хорошо сделали. Порт скал`ы под .NET, есть?
Ниже увидел ваше предположение. Глуповато вышло. Чем боролись, на то и напоролись.
Да.
> почему не добавить эти методы в сам Option
Всё из демо (кроме openOrThrowException) можно сделать и с обычной Option, она вполне себе функциональна. Просто лифтовцам нужно было много утилит, которые добавить в Option нельзя, манки-патчинг в скале запрещён.
http://www.scala-lang.org/api/current/scala/Option.html
> Порт скал`ы под .NET, есть
Говорят, можно писать на scala прямо в Visual Studio
http://www.scala-lang.org/node/10299
Извлечь из монады или кинуть исключение. Это круто вообще. В Немерле такого вроде нет( Да и вообще поддержки обобщения мейби до контенера - тоже вроде нет. (
>Просто лифтовцам нужно было много утилит, которые добавить в Option нельзя
Это типа тех, что ты показал, например map и так далее?
>манки-патчинг в скале запрещён.
Методы-расширения как под .NET?
Ну да, согласен. В Option для Nemerle можно это добавить и вручную.
>Если сходить по ссылке
Она не кликается.
На самом деле спасибо.
Тогда maybeSmth.toList.map(_.name) вернёт список, а не Option, как должно быть. Плюс лишний объект, минус более простая и быстрая реализация map.
Антиоверинженеринг:
И Box почти не нужен.
Ждем шизофреничного предложения Options<Options<T>>.
>join, т.е. преобразование M<M<T>> => M<T>
Ничего себе как продумано. Полная аналогия со списком. Уважение создателю. Вот что значит системный подход.
>Со списками чуть поинтереснее, иногда нужен именно List<List<T>>.
Ну так и не вызывай join. Какие проблемы?
PS: Пост ниже 154585 я написал несколько раньше этого поста.
bool это тоже частный случай int, но с ним же лучше, чем без него
Методы-расширения ещё ладно, хотя мне они не нравятся. Я скорее о возможности напрямую изменить поведение базовых классов, как в Ruby.
это даже круче чем #define TRUE FALSE
Плюс и минус такого решения в том, что в любом случае будут использоваться только стандартные механизмы языка, никакого метапрограммирования или особого синтаксиса. Ну, и без хаскеловской лени временами будет не очень круто, хоть и не критично (в Scala вроде можно объявить ленивую инициализацию аргумента функции, т.е. в выражении x(y + 7) часть (y + 7) будет упакована в thunk и вычислена при обращении внутри x).
Скала под .нет юзабильна? IDE с авто дополнением кода? Демонстрация выведенных типов по подводу мыши? Ну и может формошепка есть? Ну и под Java тоже самое есть?
Проще язык чем джава - найти сложно. C# и то сложнее. Если уж на то пошло, то одни из самых сложных языков для IDE - Nemerle с его диким выводом типов и диким метапрограммированием или просто дикий С++.
При этом в Немерле отличная иде, не уступающая C#. Ну и для С++ найти хорошую IDE не представляет труда, если искать, в том числе и среди плагинов.
ну да
Кстати возможность сломать семантику операторов - один из аргументов Линуса Торвальдса против C++ в ядре.
Почему так реализовали equals в самом часто используемом классе в общем-то неплохого фрэймворка - тайна. Видимо, Поллак был под веществами.
Догадовался, что они есть, но что-за условия, где прочитать?
a==b => b==a
a==b && b==c => a==c
Что ещё?
a < a => ложь
a < b && b < c => a < c
Где-то ошибся или что-то ещё забыл?
a < b -/-> b < a (relation is not simmetrical)
a < b /\ b < c --> a < c (relation is transitive)
a < a --> a < a (vacuously true :), so, reflexive)
Нужно еще учитывать, что такие операции определены не для всех множеств (например, деление на множестве натуральных чисел не определено в этом плане).
Это что-то из корабельного журнала капитана очевидность?
> a < a --> a < a
Это я совсем не понял...
"Проснулся в 8.00. Было утро."
или
"Мы плыли по морю. Кругом была вода."
vacuous truth - такая истинность, которую нельзя опровергнуть, т.как нет возможности найти пример, который бы показывал обратное утверждаемому. Для простоты будем считать, что a - натуральное число, тогда нет такого a, при котором P(a < a) = true, соответственно, доказать, что P(a < a) ~= P(a < a) не получится, т.как нам нужен, по определению, такой предикат P() который дает позитивный результат.
Но это, вобщем-то, была шутка...
а вот a < a --> a < a нету, потому что ко
да, в изначальном определении свойства говорились не про > а именно про >=
Ох бля. В джаве настолько хуёвые нативные equalsы и настолько много хинтов, граблей, правил, и исключений из них - чтобы реализовать правильно equals - это вообще целая наука. Лень даже вдаваться в детали.
Проблема настолько масштабна, что апачи даже написали специальную фабрику под названием EqualsBuilder.
Только за один equals жабу можно смело называть говном.
One does not simply implement correct equals in Java.
А как вам этот кусочек?
Ты подарил мне тот редкий момент, когда ожидаемое совпадает с действительным...
>foo == boxedFoo //is false
это скомпилируется? this же имеет тип бокс. А получается, что левая часть разбоксирована.
>(this, other) match{
И почему такой странный матчинг?
match(this, other){
В языках с OOP, где есть наследование, нельзя ограничивать тип оператора ==:
Понятно, что там ещё со ссылками разница какая то есть, но с моим знанием тамошней системы типов, опустим этот момент.
(x, y) => x eq y
Знаю, что в жабе == сравнивает по адресу ссылки, а equals сравнивает по значению. Выше я писал безотносительно этого.
А уж что здесь eq значит - не знаю.
http://govnokod.ru/11813#comment154573
Только обозначения чуть сменим:
Empty эквивалентно null
Full эквивалентно конкретному не нулевому значению.
Я не согласен. Не монадично это.
Ты не коробки сравнивать должен, а элементы, что лежат в коробке.
Для начала воспользуемся многолетним опытом исследователей из других областей.
Если мне не изменяет память (поправьте меня если я ошибусь) взгляним на NAN (Not a number) в FPU и null в SQL.
Если x - любое, то
1)x == NAN => false
NAN == x => false
NAN == NAN => false
зато isNAN(x) вернет всеж интересующий ответ на вопрос.
2)null ведет себя аналогично в SQL запросах.
x == null => false
null == x => false
null == null => false
Если ты боишься, что у тебя будут проблемы с поиском из-за нарушения рефлексии, то это не так.
Монада, например, хранит или объект\объекты или провал прошлого вычисления.
map1.find(Empty) должа вернуть Empty, а не найти закинутое каким-то идиотом по ключу Empty некое значение Full ("kokoko") например (если это ассоциативный массив).
Аналогично если расширять операции, то:
Empty*x = Empty
Также как и
NAN*х = NAN. Если сменить настройки FPU, то понятно, что нам выкинут исключение и по сути все нижележащие вычисления не обработаются, что посути тот же NAN (Empty), протащенный через всю цепочку вычислений до точки обработки в монадах.
В методе equals класса Box нужно сравнивать именно коробки.
http://www.youtube.com/watch?v=3R9K_7xuFLQ
Где аргументы? Не нужно прикрываться бумажкой мол вот стандарт и мы ему бездумно следуем. Запомните, в ресерчевых областях это не работает.
Так что совершенно логично, то одна пустота не равна другой.
Что-то типа как в F# полагаю?
http://msdn.microsoft.com/en-us/library/dd233182.aspx
Одна из реализаций этих методов seq:
http://msdn.microsoft.com/en-us/library/dd233209.aspx
или query:
http://msdn.microsoft.com/en-us/library/hh225374.aspx
Но по дефолту каких либо других монад реализованных нет.
В немерле похожим образом, только конструкция монадического сахара введена через метапрограммирование, немного пошире и по дефолту реализованы многие монады.
Там нет никакого полиморфизма, по for тупо генерится код с map, flatMap и filter, а уж потом проходит проверка типов. Определи в своей монаде эти методы, и можешь смело юзать for.
>CokleisliArrow
Это те стрелки, что в хаскеле выглядят в виде операций? По моему, сам будешь не рад, если ими будешь пользоваться...
> List(1, 2).foldRightM
Вот ты на хаскель наезжал, что мол много функций с префиксом м специально для монад, а тут таже самая проблема