元组的奇怪 Scala 'Type mismatch' 错误
Strange Scala 'Type mismatch' error for tuples
我有一个函数 map
,它接受一个 Parser
和一个定义如下的函数:
def map[T1, T2](parser: Parser[T1], func: T1 => T2): Parser[T2]
我创建了一个 Parser
类型 [(Char, Char)]
的对象和一个函数 (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
参数的类型不匹配错误 saying
Error:(26, 41) type mismatch;
found : (Char, Char) => String
required: ((Char, Char)) => String
map[(Char, Char), String](parser, 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 参数和 returns 一个 String 参数的函数。
你想要的是一个函数,它接受一个 Tuple2
和 returns 一个有点不同的字符串。
它的类型应该是Tuple2[Char, Char] => String
。
Tuple2[Char, Char]
对应于类型 shorthand (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)
FunctionN.tupled
将接受 N 个参数的函数转换为接受 TupleN
的等效函数。
这比定义一个获取元组的函数要好一些,因为圆括号会让你 运行 陷入其中,而且,因为你不必在正文中解构元组。
我有一个函数 map
,它接受一个 Parser
和一个定义如下的函数:
def map[T1, T2](parser: Parser[T1], func: T1 => T2): Parser[T2]
我创建了一个 Parser
类型 [(Char, Char)]
的对象和一个函数 (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
参数的类型不匹配错误 saying
Error:(26, 41) type mismatch;
found : (Char, Char) => String
required: ((Char, Char)) => String
map[(Char, Char), String](parser, 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 参数和 returns 一个 String 参数的函数。
你想要的是一个函数,它接受一个 Tuple2
和 returns 一个有点不同的字符串。
它的类型应该是Tuple2[Char, Char] => String
。
Tuple2[Char, Char]
对应于类型 shorthand (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)
FunctionN.tupled
将接受 N 个参数的函数转换为接受 TupleN
的等效函数。
这比定义一个获取元组的函数要好一些,因为圆括号会让你 运行 陷入其中,而且,因为你不必在正文中解构元组。