2016-03-14 3 views
3

Я хочу сделать что-то вроде этого:Scala создать числовой из строки

def parse[A: Numeric](str: String): A = { 
    if A =:= Int, str.toInt 
    if A =:= Float, str.toFloat 
    if A =:= BigInt, BigInt(str) 
    ... 
    ... 
} 

К сожалению, кажется, что нет fromString определено в Numeric черты. Какой самый идиоматический способ достичь этого в Scala?

ответ

1

То, о чем вы просите, вообще невозможно по возможности продлевать классные классы; вам не удастся сопоставить все возможные реализации Numeric, потому что любой пользовательский тип мог бы реализовать его. Кроме того, из-за этого не гарантируется, что каждый Numeric[A] будет обрабатываться из строки.

Существует два выхода из этого. Одним из них является частичное решение, в котором вы убедитесь, что используете только строки, представляющие целые литералы, а затем используйте IntfromString, чтобы разобрать его, и NumericfromInt, чтобы преобразовать его.

Другой способ - передать фактическую функцию разбора строк при вызове функции. Это может выглядеть как обман, так как ваш метод parse больше не выполняет никакой реальной работы, но может быть полезен с помощью имплицитов.

Самый простой способ - просто добавить (возможно неявный) параметр String -> A (или, может быть, String -> Option[A] за меньшее количество ошибок во время выполнения). Другой способ достичь этого - пойти the typeclass route again and implement something like a Readable typeclass. Тогда вы можете иметь свою функцию быть следующими:

def parse[A: Numeric: Readable](x: String): A = ... 

Теперь вы просто должны убедиться, что у вас есть Readable[A] реализации для всех A вы заботитесь о.

+0

Это именно то, что я здесь делаю (см. Класс типа «Scannable»): https://github.com/pathikrit/better-files/blob/master/core/src/main/scala/better/files/Scanner .scala # L79-L86 Но я хочу, чтобы числовая черта Scala имела в ней 'fromString' ... – pathikrit

+0

На самом деле теперь, когда я думаю об этом, я думаю, что есть лучший способ. Позвольте мне написать редактирование .... – badcook

+0

Не обращайте внимания; все, что я могу думать, просто возвращается в одно и то же. Единственное, что я мог подумать, это, пожалуй, использование «spire» и использование его «Integral» typeclass, а затем сопоставление того, является ли это «Fractional» или просто «Integral», а затем использовать соответствующие методы 'fromDouble' или' fromInt' (вместе с 'toDouble' и' toInt') для его анализа. Ваш «Scannable» кажется прекрасным, но я бы не стал называть себя экспертом Scala и откладывал на других. – badcook

Смежные вопросы