Сопоставление с шаблоном Scala для кортежа с параметрами все еще требует развертывания в некоторых случаях - PullRequest
1 голос
/ 09 мая 2019

f(Int) - это функция, которая возвращает Option[Int].

def findIntPair(x: Int, y: Int): (Int, Int) = {
    (f(x), f(y)) match {
      case (None, None) || (None, _) || (_, None)  => fail("Unable to find the pair" )
      case (a, b) => (a.get, b.get) // why I still need to unwrap by get
    } 
}

Почему последние case(a, b) не разворачивают их в Int, но сохраняют их как Option[Int]?

К вашему сведению: я использую IntelliJ IDEA.

Ответы [ 4 ]

4 голосов
/ 09 мая 2019

Вам необходимо сопоставить шаблон с Some:

def findIntPair(x: Int, y: Int): (Int, Int) = {
    (f(x), f(y)) match {
      case (None, None) || (None, _) || (_, None)  => fail("Unable to find the pair" )
      case (Some(a), Some(b)) => (a, b)
    } 
}

Немного чище с использованием универсального case _:

def findIntPair(x: Int, y: Int): (Int, Int) = {
    (f(x), f(y)) match {
      case (Some(a), Some(b)) => (a, b)
      case _  => fail("Unable to find the pair" )
    } 
}
1 голос
/ 09 мая 2019

Я думаю, что правильное решение состоит в том, что вы делаете это следующим образом:

   (f(x), f(y)) match {
     case (None, None) | (None, _) | (_, None)  => fail("Unable to find the pair" )
     case (Some(a), Some(b)) => (a, b) 
   }
 }
0 голосов
/ 09 мая 2019

Это потому что:

def findIntPair(x: Int, y: Int): (Int, Int) = {
    (f(x), f(y)) match {
      case (None, None) || (None, _) || (_, None)  => fail("Unable to find the pair" )
      case (a, b) => (a.get, b.get) //here f(x) = a and f(y) = b
    } 
}

Вы хотите что-то вроде этого:

def findIntPair(x: Int, y: Int): (Int, Int) = {
(f(x), f(y)) match {
  case (None, None) || (None, _) || (_, None)  => fail("Unable to find the pair" )
  case (Some(a), Some(b)) => (a, b)
} 

}

Но это не лучший способ сделать это, я думаю, что это лучше:

def findIntPair(x: Int, y: Int): (Int, Int) = {

    if(f(x).isDefined && f(y).isDefined) (f(x).get,f(y).get)
    else fail("Unable to find the pair" )

}
0 голосов
/ 09 мая 2019

Вот альтернативный способ выражения этой логики:

def findIntPair(x: Int, y: Int): Option[(Int, Int)] =
  for {
    a <- f(x)
    b <- f(y)
  } yield (a,b)

Преимущество в том, что он не будет вычислять f(y), если f(x) вернет None. Эта версия возвращает Option, чтобы ошибка могла быть обработана позже, но вы можете обработать ее внутри функции следующим образом:

def findIntPair(x: Int, y: Int): (Int, Int) =
  (
    for {
      a <- f(x)
      b <- f(y)
    } yield  (a, b)
  ).getOrElse(fail("Unable to find the pair"))

Обратите внимание, что это предполагает, что fail возвращает (Int, Int), что необходимо для работы кода в вопросе.

...