Вопрос

Как предназначено для работы варианта монада? Я просматриваю Scala API и есть пример (я имею в виду второй),

Из-за того, как для понимания работает, если никто не возвращается из запроса .getParameter, все выражение приводит к ним

Но когда я пробую этот код:

 val upper = for {
   name <- None //request.getParameter("name")
   trimmed <- Some(name.trim)
   upper <- Some(trimmed.toUpperCase) if trimmed.length != 0
 } yield upper
 println(upper.getOrElse(""))

Я получаю ошибку компиляции. Как это должно работать?

Это было полезно?

Решение

Вы получаете ошибку компилятора из-за этого

  name <- None

Таким образом, тип None установлен в None.type и переменная name выводится, чтобы иметь тип Nothing. Отказ (То есть у него будет такой тип, если он фактически существует, но, очевидно, то для понимания даже не может создавать его во время выполнения.) Поэтому нет метода name.trim существует, и это не скомпилируется.

Если у тебя есть request.getParameter("name") доступно, его тип будет Option[String], name потенциально будет иметь тип String и name.trim будет компилировать.

Вы можете работать вокруг этого, указав тип None:

  name <- None: Option[String]

Другие советы

Чтобы расширить ответ Кевина, вы можете избежать оборотных значений в Some() Используя = оператор вместо <- Оператор:

val upper = for {
   name <- None: Option[String] //request.getParameter("name")
   trimmed = name.trim
   upper = trimmed.toUpperCase if trimmed nonEmpty
} yield upper

Для понимания будет сознавать что-то очень похожее на версию Кевина, но я часто считаю более понятными для использования map и filter Явно, чтобы избежать беспорядка (например, дополнительные имена переменного), которые ничего не добавляют к семантическому содержанию выражения.

Чтобы расширить ответ Дебильского, вам также не нужно явно обернуть последующие значения в Some(), единственное значение, которое вы на самом деле отображаете, является оригиналом name.

Лучший подход будет использовать map и filter Операции напрямую вместо понимания:

Примечание. За кулисами Scala Compiler преобразует средство для понимания в комбинацию MAP / Flatmap / Filter в любом случае, поэтому этот подход никогда не будет менее эффективным, чем для понимания, и вполне может быть более эффективным

def clean(x:Option[String]) = x map { _.trim.toUpperCase } filterNot { _.isEmpty }

val param = None : Option[String] // request.getParameter("name")
println( clean(param).getOrElse("") )
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top