Пройдите через кошку / скалаз - PullRequest
0 голосов
/ 07 октября 2018

Я хочу пройти строку следующим образом:

import cats.implicits._

object RnaTranscription {
  val mMap: Map[Char, Option[Char]] =
    Map('G' -> Some('C'),
        'C' -> Some('G'),
        'T' -> Some('A'),
        'A' -> Some('U')).withDefaultValue(None)

  def toRna(dna: String): Option[String] = {
    dna.toList.traverse(mMap).map(_.mkString)
  }
}

Но у него есть дополнительные шаги, мне нужно привести к List[Char], а затем снова mkString, есть ли способ вкошки или скалязы, чтобы пройти строку без приведения в список?

Ответы [ 2 ]

0 голосов
/ 08 октября 2018

Как подразумевал @BogdanVakulenko в своем ответе, String не является Функтором (F[_]).

Класс типов Traverse у кошек имеет следующее объявление:

@typeclass trait Traverse[F[_]] extends Functor[F] with Foldable[F] with UnorderedTraverse[F] { self => ... }

Способ, которым вы решили это с помощью toList и mkString, мне подходит, но, если вы хотите простую ванильную версию Scala, которая работает:

  def toRnaScala(dna: String): Option[String] = {
    val maybeChars: immutable.Seq[Option[Char]] = dna.map(mMap)
    maybeChars.foldLeft(Option("")) {
      case (acc, Some(c)) => acc.map(_ + c)
      case (_, None) => None
    }
  }
0 голосов
/ 07 октября 2018

Может быть, что-то вроде этого:

def toRna(dna: String): Option[String] = {
  Some(dna.map(mMap).flatten.mkString)
}

Нет способа использовать traverse для строки напрямую, поскольку string является нативной структурой java.Внутри cats / scalaz существует неявное преобразование, которое добавляет метод traverse в коллекции.Это неявное может применяться только для типов с одним параметром типа ((* -> *) или F[_]).Строка - это просто T, поэтому scala не может применить это неявное преобразование.

implicit def toTraverseOps[F[_], C](target : F[C])
            (implicit tc : cats.Traverse[F]) : Traverse.Ops[F, C]
...