Подтвердить что ты не робот

Где вы разделяете длинные сигнатуры функций Scala?

Определение типа

def foo(x: Int) = x + 1

приятный и короткий и выглядит красиво, но когда сама подпись становится неудобной,

def foo[T <: Token[T]](x: ArrayBuffer[T], y: T => ArrayBuffer[() => T]): (T, T, BigDecimal) = {
    // ...
}

Я не знаю, где его разделить. Я считаю, что все следующее выглядит неудобно:

def foo(
    x: Int,
    y: Int
): Int = {
    // ...
}

def foo(
        x: Int,
        y: Int
    ): Int =
{
    // ...
}

def foo(
        x: Int,
        y: Int
    ): Int
= {
    // ...
}

def foo(
        x: Int,
        y: Int
    ):
Int = {
    // ...
}

Но, учитывая, что мне придется привыкнуть к одному из них, что вызовет наименьшее раздражение моих товарищей по команде?

4b9b3361

Ответ 1

Scala руководство по стилю не имеет права говорить об этом. На самом деле он рекомендует использовать методы с меньшим количеством параметров: -).

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

foo(someVeryLongFieldName,
    andAnotherVeryLongFieldName,
    "this is a string",
    3.1415)

Лично в вашем случае я бы разделился по правилу "держать как вместе":

def foo[T <: Token[T]]
       (x: ArrayBuffer[T], y: T => ArrayBuffer[() => T])
       : (T, T, BigDecimal) = {
  // ...
}

Итак, параметры находятся в одной строке, тип возврата - в одной строке, а ограничение типа - в одной строке.

Ответ 2

В Haskell длинные сигнатуры часто записываются таким образом:

someFunc :: (Some Constraints Go Here)
         => Really Long Arg1 Type
         -> Really Long Arg2 Type
         -> Really Long Result Type
somefunc x y = ...

Чтобы перевести этот Haskellism в Scala,

def foo [ T <: Token[T] ]
        ( x : ArrayBuffer[T]
        , y : T => ArrayBuffer[() => T]
        )   : (T, T, BigDecimal) = {
    // ...
}

Вот как я это сделаю. Не знаете, как кошерно это с сообществом Scala.