Проблема в , а не в том, что вы не можете присвоить ему значение бездействия (по умолчанию); проблема в том, что даже если вы это сделаете, функции с несколькими блоками параметров должны иметь минимум иметь круглые скобки или фигурные скобки для каждого блока.
Существует одно исключение: на блок параметров неявный вообще не нужно ссылаться. К сожалению, вам не разрешено иметь неявные параметры по имени, и даже если бы вы были, ваша подпись позволила бы любому случайному неявному сработать в этом месте!
Теперь, есть способ обойти это, который я покажу для полноты, но я предлагаю, что (при условии, что вам не нужно просто другое имя, например leafNode
), вы просто оставляете конечный {}
там.
Вы можете получить именно тот синтаксис, который вам нужен, если вы выполните следующее. Во-первых, вам нужен неявный параметр, но вы делаете его классом-оболочкой (может использовать Function0
, который уже существует, но затем следующий шаг может иметь непредвиденные последствия):
trait AnyByName { def eval: Any }
def treeNode(text: String)(implicit children: AnyByName) = (text,children.eval)
Теперь вам нужны две вещи - вы должны иметь возможность преобразовать имя по имени Any
в вашу новую черту, и вам нужно иметь неявную доступную ничего не делающую. Итак, мы
implicit val nameForDoingNothing = new AnyByName { def eval = () }
implicit def wrap_any_by_name(a: => Any) = new AnyByName { def eval = a }
А теперь мы возвращаемся к тому поведению, за которым вы были:
scala> treeNode("Hi")
res1: (String, Any) = (Hi,())
scala> treeNode("Hi") { treeNode("there") }
res2: (String, Any) = (Hi,(there,()))
(в вашем примере вы ничего не возвращаете; здесь я показываю, что это работает.)
Это много инструментов, чтобы избежать некоторых {}
с, поэтому я рекомендую делать это только в том случае, если вы ожидаете, что это очень интенсивно используемые DSL и с двумя именами. недопустимо (Кроме того, если вы ожидаете, что он будет очень интенсивно использоваться, treeNode
, вероятно, мучительно длинное имя; я бы предложил просто node
.)