Я бы сказал, ваша проблема в том, что у вас есть два типа, над которыми вы хотите работать: Int и String, и вы хотите выполнить метод ключа для этого ввода, но вы не указываете, чтоВы хотели бы вернуться.
Моей первой идеей для Int было бы вернуть Int.toString (). charAt (n) кажется формой мошенничества, но, возможно, мошенничество в порядке, поэтому давайте начнем мошенничать:
def cheat (a: Any, n: Int) = a.toString ().charAt (n)
cheat (2345, 2)
// res414: Char = 4
cheat ("foobar", 2)
// res415: Char = o
Это было приятно и просто, не так ли?Но что, если вы хотите вернуть Int для ввода Int и String для ввода String?Char кажется более естественным для ввода типа String, и байта будет достаточно, чтобы вернуть цифру от 0 до 9, но у нас будет более простая зависимость от типа, если мы вернем T для T.
IЯ не убежден в своем решении, но я не убежден в мошенничестве, и первые решения - это только более сложный способ мошенничества, не так ли?
class Atti [T] (val fun: (Int => T)) {
def at (n: Int): T = fun (n)
}
Я определил класс atti, который для типа T нуждается в функции, которая принимает Int и возвращает T, и если вы вызовете at
для этого класса, он вызоветэта функция.
Теперь мы определяем функцию iGet, чтобы получить из Int цифру в позиции n, и мы используем два списка параметров, ...
def iGet (i: Int) (n: Int) : Int = {
if (n == 0) i % 10
else iGet (i / 10)(n - 1) }
... для передачи Int, на котором можно без труда определить частично определенную функцию:
val iAt = new Atti[Int] (iGet (2345) _)
(0 to 3).map (iAt.at (_))
// res412: scala.collection.immutable.IndexedSeq[Int] = Vector(5, 4, 3, 2)
Аналоговая функция для строки и объявление sAt:
def sGet (s: String) (n: Int) : String = "" + s.charAt (n)
val sAt = new Atti[String] (sGet ("foobar") _)
(0 to 3).map (sAt.at (_))
// res413: scala.collection.immutable.IndexedSeq[String] = Vector(f, o, o, b)
Полагаю, вы видите, чтоСтрока оценивается слева направо, а Int - справа налево, как в вашем введении в проблему.
Мне не нравится то, что sAt с полезной нагрузкой 'foobar' неСтрока больше, и 2345 каким-то образом скрыт в iAt-объекте.
И функцию, которую следует использовать для строки, необходимо указывать для каждой строки, что дает вам большую гибкость, чем вы просили, и больше работы для каждого экземпляра.
Я пытался создать черту и смешать ее с Int или String, но безуспешно:
trait Key [T] { def at (n: Int): T }
val s : String with Key[String] = "Foobar" { def at (n: Int) : String = "" + s.charAt (n) }
<console>:7: error: type mismatch;
found : Unit
required: Int
val s : String with Key[String] = "Foobar" { def at (n: Int) : String = "" + s.charAt (n) }
^