как сопоставить шаблон с первым символом в строке - PullRequest
0 голосов
/ 31 мая 2018

Я просто изучаю scala и работаю над созданием кода в качестве упражнений.Я знаю, что сопоставление с образцом популярно в Haskell и надеется сделать то же самое в scala.

def part1(visited: Set[Coord], current: Coord, directions: String):  Set[Coord] = directions match {
  case "^" :: tail => part1(visited + current, current.up, tail)
  case "v" :: tail => part1(visited + current, current.down, tail)
  case "<" :: tail => part1(visited + current, current.left, tail)
  case ">" :: tail => part1(visited + current, current.right, tail)
  case _ => visited + current // The string is empty
}

Я пытался конвертировать, используя Array или List символов вместо строки, но продолжаю застревать.Код, который я вставил выше, сообщает:

Day3.scala:8: error: constructor cannot be instantiated to expected type;
 found   : scala.collection.immutable.::[B]
 required: Array[Char]
    case '^' :: tail => part1(visited + current, current.up, tail)
             ^

Ответы [ 2 ]

0 голосов
/ 31 мая 2018

::, также известный как Cons, является конструктором для List, который имеет голову и хвост.У вас есть Array[Char], представляющий String, поэтому вы не можете использовать семантику List, если вы явно не конвертируете в List[Char].Что вы можете сделать, так это использовать охрану:

def part1(visited: Set[Coord], current: Coord, directions: String):  Set[Coord] = 
  directions match {
    case x if x.startsWith("^") => part1(visited + current, current.up, x.tail)
    case x if x.startsWith("v") => part1(visited + current, current.down, x.tail)
    case x if x.startsWith("<") => part1(visited + current, current.left, x.tail)
    case x if x.startsWith(">") => part1(visited + current, current.right, x.tail)
    case _ => visited + current // The string is empty
}

Примечание tail исходит от IndexedSeqOptimized, а не напрямую от String.

0 голосов
/ 31 мая 2018

:: определено только для списков, и хотя String s можно неявно преобразовать в Seq, результат не является List - вы можете использовать toList для преобразования Seq вList.Кроме того, используйте одинарную кавычку для создания Char, а не строки:

directions.toList match {
  case '^' :: tail => // ...
  case 'v' :: tail => // ...
  case '<' :: tail => // ...
  case '>' :: tail => // ...
  case _ => // ...
}

В качестве альтернативы, вы можете сопоставить только результат headOption (вернуть первый символ или None):

directions.headOption match {
  case Some('^') => // ...
  case Some('v') => // ...
  case Some('<') => // ...
  case Some('>') => // ...
  case _ => // ...
}
...