【问题标题】:Scala infix type aliasing for >2 type parameters?> 2个类型参数的Scala中缀类型别名?
【发布时间】:2014-06-13 13:46:46
【问题描述】:

我知道在 Scala 中,你可以使用type ===>[A, B] = Map[A, B],然后你可以使用中缀符号来定义def foo: String ===> Int,这与def foo: Map[String, Int] 相同。有没有办法利用这个中缀符号来创建具有 >2 个参数的类型?例如,我想要这样的东西:

type A ~> B ~~~> CMap[A, Pair[B, C]] 的别名?

有没有我可以这样写:

type A to B -> C 作为(A, B, C) 类型的别名?

【问题讨论】:

    标签: scala scalaz type-alias


    【解决方案1】:

    有趣的是,operator precedence as defined for symbolic methods 似乎不适用于符号类型别名。相反,中缀类型别名总是被评估为左关联:

    type -[A,B] = Map[A,B] 
    type /[A,B] = Map[A,B] // '/' has higher precedence than '-' as an operator
    classOf[A - B / C] // Class[/[-[A,B],C]]
    classOf[A / B - C] // Class[-[/[A,B],C]]
    

    不幸的是,这意味着如果没有这样的括号,就永远不可能做你要求的事情:

    classOf[A - (B / C)] // Class[-[A,/[B,C]]
    

    所以最接近的答案如下:

    type ~>[A,B] = Map[A,B]
    type ~~~>[A,B] = Pair[A,B]
    classOf[A ~> (B ~~~> C)] // Map[A,Pair[B,C]]
    

    只有在使用右关联别名(以 : 结尾)时才能省略括号

    type ~:[A,B] = Map[A,B]
    type ~~~:[A,B] = Pair[A,B]
    classOf[A ~: B ~~~: C] // Map[A,Pair[B,C]]
    

    再次遗憾的是,由于所有类型别名都具有相同的优先级,因此不可能在没有括号的情况下混合左右关联别名。

    关于您问题的第二部分:(A,B,C)Tuple3[A,B,C] 的语法糖,它是具有三个参数的类型。由于中缀类型只需要两个参数,恐怕我相信没有办法仅用中缀类型来表示这种类型。你总是会得到嵌套的两种参数类型(例如(A,(B,C))((A,B),C)

    【讨论】:

    • 很好的说明。直到您的回答才意识到优先级不一样!
    • 是否可以实现A as B ~> C 表示(A, B, C)
    • @wrick:我认为这在类型级别上是不可能的。中缀类型只能接受两个类型参数,但 (A,B,C) 有三个。恕我直言,只有 ((A,B),C) 或 (A,(B,C)) 是可能的。
    【解决方案2】:

    简短的回答:不。 A ~> B ~> C 不能代表Map[A, Pair[B, C]]

    不过,它可以表示Map[A, Map[B, C]],或Pair[A, Pair[B, C]]

    【讨论】:

    • 如果我使用两个符号,例如A ~> B ==> C ?
    • 如果你得到这些中缀“类型构造函数”的优先权,那么你的例子就是Map[A, Pair[B, C]]而不是Pair[Map[A, B], C]。请务必查看 Scala 语言规范的第 6.12.3 节。
    • A ~> B ~> C 不能表示Map[A,Map[B,C]]。没有括号的任何东西都不能表示Map[A,Pair[B,C]]。看我的回答。
    猜你喜欢
    • 2014-10-06
    • 2021-11-06
    • 1970-01-01
    • 1970-01-01
    • 2012-04-11
    • 2013-03-18
    • 1970-01-01
    • 1970-01-01
    • 2012-01-04
    相关资源
    最近更新 更多