我有一个函数map
,它接受一个Parser
和一个定义如下的函数:
def map[T1, T2](parser: Parser[T1], func: T1 => T2): Parser[T2]
我已经创建了一个类型为[(Char, Char)]
的Parser
对象和一个函数(Char, Char) => String
。
val parser[(Char,Char)] = //...
val asString: (Char, Char) => String = (a: Char, b: Char) => a.toString + b.toString
然后我把这两个传递给map
函数。
val mParser: Parser[String] = map(parser, asString)
我希望一切都能正常工作,但asString
参数的出现类型不匹配错误
错误:(26,41(类型不匹配;
找到:(Char,Char(=>字符串
必需:((Char,Char((=>字符串
map[(Char,Char(,String](解析器,asString(
我曾尝试将map
的类型显式指定为map[(Char, Char), String](parser, asString)
,但这也没有帮助。
这里的类型T1
是字符元组(Char, Char)
,而T2
是String
。因此,函数(Char, Char) => String
应该是输入,但scala期望的是不同的类型。
我在这里错过了什么?为什么期望((Char, Char)) => String
而不是(Char,Char) => String
?
我使用的是Scala 2.12。不知道这在任何方面是否相关。
非常感谢你的帮助。
类型(Char, Char) => String
对应于一个函数,该函数接受两个Char参数并返回一个String。
你想要的是一个函数,它接受一个Tuple2
并返回一个不同的String。
其类型应为Tuple2[Char, Char] => String
。Tuple2[Char, Char]
对应于类型简写(Char, Char)
,但我猜在函数定义期间,编译器会将括号解释为用于对函数参数进行分组。
这是一个已知的问题,它正在scala3中得到解决。https://dotty.epfl.ch/docs/reference/auto-parameter-tupling.html
正如其他人所指出的,定义一个接受Tuple2
而不是两个参数的函数会有点棘手,而且看起来很难看。
一个很好的方法是使用.tupled
:
val asString: (Char, Char) => String = (a: Char, b: Char) => a.toString + b.toString
val mParser: Parser[String] = map(parser, asString.tupled)
CCD_ 24将接受N个自变量的函数转换为取CCD_。这比定义一个接受元组的函数要好一点,因为你会遇到括号的怪癖,而且你不必解构主体中的元组。