Карта функций Scala - PullRequest
       0

Карта функций Scala

1 голос
/ 24 марта 2011

Я только начинаю изучать scala, и, возможно, я немного амбициозен. Я хотел сопоставить String с функцией от String до Boolean. К сожалению, я не совсем понимаю обратную связь, которую я получаю от компилятора. Вот код:

class StdRead {
    def read(key : Array[Int], value : Array[Int],seperator : Array[Char],
        filter : Map[Int, String => Boolean], write : String => Unit) {
    for( ln <- stdin.getLines ) {
        val inarr = ln split seperator 
        for(i <- key) {
            val func = filter get i //func : Option[(String) => Boolean]
            val f = func getOrElse Unit //f : java.lang.Object
            val res = func(inarr(i)) //Error, doesn't work
        }
        //more stuff        
    } 
}

Прежде всего, почему я получаю Option, это единственный способ получить доступ к функции. Во-вторых, почему возвращение getOrElse является объектом? Разве это не то, что я могу использовать для вызова функции? Было бы здорово, если бы кто-нибудь дал мне простой пример того, что мне нужно делать здесь.

Заранее спасибо.

Ответы [ 2 ]

4 голосов
/ 24 марта 2011

Как заметил Рекс, тип Map.get - A => Option[B], тогда как метод apply имеет тип A => B, но это ложь, потому что он может вызвать исключение.В целом, я бы посоветовал не использовать форму заявки из-за этой лжи.

В вашем конкретном примере вам, вероятно, вообще не следует использовать getOrElse;вместо этого, поскольку то, что вы делаете, в любом случае просто вызывает побочный эффект, попробуйте что-то вроде следующего.Я изменил название «фильтр», потому что на самом деле это также имя важного метода на Map и других итерациях, и перегрузка этого имени - ненужный источник путаницы.

class StdRead {
  def read(key : Array[Int], value : Array[Int],seperator : Array[Char],
      stringTests : Map[Int, String => Boolean], write : String => Unit) {
    for { 
      ln <- stdin.getLines 
      val inarr = ln split seperator 
      i <- key
      stringTest <- stringTests.get(i)
    } {
      stringTest(inarr(i))
    }
  }
}

Обратите внимание, что вы можете объявитьзначения внутри выражений для понимания.Помните, что это не петли!

3 голосов
/ 24 марта 2011

Если вы уверены, что у карты есть определенный ключ, вы можете просто взять его напрямую: filter(i).Метод get используется, если вы не уверены (или быть более осторожным в отношении ошибок).Возвращает опцию, из которой вы правильно решили использовать getOrElse.Однако вы хотите getOrElse( (s:String) => /* some boolean */), то есть вы должны также вернуть функцию от String до Boolean.Затем вы можете применить f, которая будет либо успешно полученной функцией с карты, либо любой функцией по умолчанию, которую вы указали в getOrElse.

Что произошло, когда вы сказали, чтобы она возвращала Unit, было то, чтоон подумал, так сказать: «Ну, вы говорите, что если это там, то это функция, а если это не единица… это означает, что все, что я могу сказать о типе, это то, что это объект».

В любом случае, что-то вроде

val f = func getOrElse (s: String) => true
val res = inarr.filter(f)

будет делать то, что, как я думаю, вы пытаетесь сделать (то есть фильтровать массив inarr с помощью функции, извлеченной из карты).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...