1

所以我最近阅读了以下打击帖子: http: //www.chuusai.com/2011/06/09/scala-union-types-curry-howard/

我真的很欣赏这种方法!我正在尝试制作一个功能

def neq[A,B] = ...

其中 neq[String, String] 不会编译,但 neq[String, Int] 会。看起来这应该是可能的,但我认为我没有足够深入地理解我们可以使用 curry-howard 对类型中的逻辑进行编码的方式。

我失败的尝试如下:

我认为我们想要的本质上是一个异或。所以我们想要

A and ~B or ~A and B

由于在进行隐式解析时我们在 scala 中所拥有的只是 <:<、=:= 之类的东西,我认为我需要在其中包含一个暗示,因为那是 <:<。所以我们说:

~(A and ~B) => (~A and B)

但是,如果我尝试执行以下操作,这将不起作用:

implicitly[((String with (Int => Nothing)) => Nothing) <:< ((String => Nothing) with Int)]

这是有道理的,因为类型根本不匹配。所以我真的不知道该去哪里!希望得到任何指导。

4

1 回答 1

2

据我了解,您需要保证 A 和 B 的不等式(如果我错了,请纠正我)

Shapeless库中的好解决方案(来自 Miles Sabin) :

// Type inequalities
trait =:!=[A, B] 
def unexpected : Nothing = sys.error("Unexpected invocation")

implicit def neq[A, B] : A =:!= B = new =:!=[A, B] {}
implicit def neqAmbig1[A] : A =:!= A = unexpected
implicit def neqAmbig2[A] : A =:!= A = unexpected

你的neq方法看起来像:

def neq[A,B](implicit ev : A =:!= B) = ...

更新:

异或:

A and ~B or ~A and B

通过隐式决议不是:

~(A and ~B) <:< (~A and B)

正确的转换是:

(A and ~B) <:!< (~A and B)
or:
(A and ~B) =:!= (~A and B)

比scala代码:

type xor[A, B] = (A with ![B]) =:!= (![A] with B)

def neq[A,B](implicit ev : A xor B) = ...

和测试:

neq[Int, String]          // - ok
neq[String, Int]          // - ok
//neq[String, String]     // - compilation error
//neq[Int, Int]           // - compilation error

毕竟,它可以简化为:

A =:!= B
于 2014-07-11T07:29:57.077 回答