键入Scala组合器演算数据模型的推断
-
13-10-2019 - |
题
我正在尝试对Scala中的组合物进行的非常轻巧的编码。最初,我只是仅实现S和K组合器,应用和常数值。稍后,我希望提起Scala功能,并允许将表达式评估为Scala函数。但是,这是稍后的。这是我到目前为止所拥有的。
/** Combinator expression */
sealed abstract class CE
/** Application: CE| (x y) <=> LC| (x:(A=>B) y:A) : B */
case class Ap[A <: CE, B <: CE, X](e1: A, e2: B) extends CE
/** A raw value with type */
case class Value[T](v: T) extends CE
/** Some combinator */
sealed abstract class Comb extends CE
/** The S combinator: CE| S x y z
* LC| λx:(A=>B=>C).λy:(A=>B).λz:A.(x z (y z)) : C
* S : ∀A.∀B.∀C. (A => B => C) => (A => B) => A => C
*/
case object S extends Comb
/** The K combinator: CE| K x y
* LC| λx:A.λy:B.x:A : A
* K : ∀A => ∀B => A
*/
case object K extends Comb
现在,我想对此进行某种类型的推论。为了简单地实施小型和大型降低,数据模型是未型的,因此我希望类型是该结构的外部。让我们介绍一些类型信息。
trait TypeOf { type typeOf }
值类型很容易。
implicit def typeOfValue[T](vt: Value[T]) : TypeOf =
new TypeOf { type typeOf = T }
应用程序更加棘手,但基本上归结为功能应用。让我们介绍一种用于组合应用程序应用的类型,以避免与普通的Scala应用混淆。
/** Combinator application */
class ⊃[+S, -T]
implicit def typeOfAp[Ap[A, B], A <: CE, B <: CE], X, Y](Ap(A, B)
(implicit aIsFXY: A#typeOf =:= (X⊃Y), bIsX: B#typeOf =:= X) : TypeOf =
{ type typeOf = Y }
这就是我被卡住的地方。我需要代表S和K组合器的类型。但是,它们是普遍量化的类型。在开始应用它们之前,您不知道它们的实际类型。让我们以K为例。
(K x:X y:Y) : X
(K x:X) : ∀Y.Y => X
(K) : ∀X.x => ∀Y.Y => X
我尝试使用此操作的前几次,我将K参数化为K [X,Y],但这(灾难性)不足。 K的类型应等待第一个参数的类型,然后等待下一个参数的类型。如果仅将k应用于一个值,则不应修复下一个参数的类型。您应该能够(k x:x)将其应用于字符串,或将其应用于int或任何类型的类型。
因此,我的问题是如何编写为S和K生成类型的隐式,以及如何正确处理∀量化类型。也许我想要这样的东西?
implicit def typeOfK(k: K.type): TypeOf = { type typeOf = ∀[X, X ⊃ (∀[Y, Y⊃X])] }
但是,我不确定应该如何编写∀类型来进行管道。我觉得除了正确处理∀之外,TypeOfap还会有第二个隐含的内容来处理a#typeof =:=∀[...],除了退出#typeof =:=⊃:=⊃[ ...] 一。
谢谢,
马修
解决方案
这有帮助吗?
trait λ {
type ap[X] <: λ
}
type K = λ {
type ap[X<:λ] = λ {
type ap[Y<:λ] = X
}
}
type S = λ {
type ap[X<:λ] = λ {
type ap[Y<:λ] = λ {
type ap[Z<:λ] = X#ap[Z]#ap[Y#ap[Z]]
}
}
}
type I = S#ap[K]#ap[K]
def ap[X<:λ,Y<:λ](x:X,y:Y): X#ap[Y]
不隶属于 StackOverflow