Тема: Оператор (чи case class) Some в Scala

Є на цьому форумі хоч один scala-майстер? Ну або хоча б падаван, який міг би це розтлумачити на пальцях? А також, можна підказати якусь нормальну літературу по scala, де буде дійсно пояснено, а не так як "як намалювати сову".

2

Re: Оператор (чи case class) Some в Scala

Пробував скалу десь рік тому, з case-класами в цілому і з Some зокрема не було ніяких проблем. Що саме незрозуміло?

3

Re: Оператор (чи case class) Some в Scala

Наскільки Я зрозумів, то Some вертає true для будь чого не Null, не None і т.д., але... (правда, наступна проблема може і не в Some, та все ж таки) - беремо цю лібу https://github.com/scopt/scopt

Бачимо жахливий шматок коду, який якимось дивним чином таки працює (у мене теж запрацював), і ось що бентежить найбільше:
1) немає явного імпорту цього scopt
2) звідки взявся config (саме з маленької літери):

// parser.parse returns Option[C]
parser.parse(args, Config()) match {
  case Some(config) =>
    // do stuff

  case None =>
    // arguments are bad, error message will have been displayed
}

Коротше кажучи, як та вся фігня працює?

п.с. програми та інтерфейси повинні створюватися для людей, а не для комп'ютерів, а тут якраз все з точністю до навпаки

4

Re: Оператор (чи case class) Some в Scala

Як воно працює без явного імпорту не відповім: давно користувався Скалою і навіть тоді не факт що зустрічався з чимось подібним.

Наскільки Я зрозумів, то Some вертає true для будь чого не Null, не None і т.д.,

і зрозуміли неправильно. case Some(config) - це зовсім не виклик функції, а порівняння з шаблоном.

Метод parse в будь-якому разі поверне Option. Але якщо парсинг пройшов вдало, конкретний Option буде Some(якесь_корисне_значення), після чого ви можете використати його в блоці match:

case Some(config) =>
  // do stuff
  System.out.println(config)

тобто config в даному випадку є іменем корисного значення. Ну а в випадку невдалого парсингу ніякого корисного значення немає, повертається None без аргументів.

5

Re: Оператор (чи case class) Some в Scala

Тобто, це виходить ніби:

var config = parser.parse(args, Config())
if (config) // do stuff
else // arguments are bad

ось так воно чи шо?

та шоб таких розробників мови в туалет пускали лише опісля видачі робочого коду

6

Re: Оператор (чи case class) Some в Scala

Master_Sergius написав:

Тобто, це виходить ніби:

var config = parser.parse(args, Config())
if (config) // do stuff
else // arguments are bad

ось так воно чи шо?

та шоб таких розробників мови в туалет пускали лише опісля видачі робочого коду

Не поспішайте з висновками. Якщо говорити про клас Option, то на перший погляд він надлишковий: там, де Some(value), можна повернути просто value, а там, де None, повертати null. Проте сам факт того, що функція повертає Option, вимагає від програміста обробити обидві ситуації. Це схоже на звичайні джавівські Exception`и, але Exception - це виняткова ситуація, яка забирає багато ресурсів, в той час як None може бути використаний і для штатної ситуації.

Крім того, бувають і складніші case-класи. Наприклад, клас, що представляє гральні карти:

abstract class Card
case class Joker extends Card
case class Higher(suit: Suit, value: String)
case class Lower(suit: Suit, value: Int) 

Порівняння з шаблоном такого класу виглядатиме досить просто:

card match{
  case Joker => //
  case Higher(suit, stringValue) => //
  case Lower(suit, intValue) => //

тоді як коректний ланцюжок if-else-... мені важко уявити сходу.

7

Re: Оператор (чи case class) Some в Scala

От якраз то з картами все зрозуміло, а з тими речами важче. Можете запропонувати такий гарний і зрозумілий приклад із Some, Option? Мабуть гірше за це може бути тільки розбір монад в Haskell

8

Re: Оператор (чи case class) Some в Scala

Гірше за розбір монад? В Хаскелі є монада Maybe, в якої є два конструктори: Just x і Nothing. Її використання в простих випадках аналогічне використанню відповідно Option, Some(x) і None. Правда, в Скалі цей тип не має властивості монади.

Option варто використовувати там, де щось може піти не так, але це все ще залишатиметься штатною ситуацією. Наприклад, безпечне ділення:

//на правах пседокоду
def safeDivide(a:Int, b:Int):Option[Int]{
  if(b == 0){
    None
  }else{
    Some(a/b)
  }
}

safeDivide(1, 0) match {
  Some(x) => //використали x
  None      => //зробили щось інше
}
Подякували: Master_Sergius1

9

Re: Оператор (чи case class) Some в Scala

Ну ось так уже краще, більш наочно і зрозуміло. Дякую. Але python рулить! Єдиний поки недолік - мультипоточність, але це вже зовсім інша історія