了解纯文字变体

时间:2018-12-10 13:12:27

标签: purescript

新手在这里。我试图了解purescript-variant背后的一些机制。基本上,我的意思是如何理解这两个功能:injon

当我查看 private void writeOrientation(int orientation, String path) { try { int exifOrientation = ExifInterface.ORIENTATION_NORMAL; if (45 < orientation) { if (orientation <= 135) { exifOrientation = ExifInterface.ORIENTATION_ROTATE_90; } else if (orientation <= 225) { exifOrientation = ExifInterface.ORIENTATION_ROTATE_180; } else { exifOrientation = ExifInterface.ORIENTATION_ROTATE_270; } } ExifInterface exif = new ExifInterface(path); exif.setAttribute(ExifInterface.TAG_ORIENTATION, String.valueOf(exifOrientation)); exif.saveAttributes(); } catch (Exception e) { Log.w(TAG, "Failing to write orientation: " + e.getMessage()); Log.getStackTraceString(e); } } 的类型时,作者使用了Cons类型类。据我了解,inj断言存在一条记录Cons,可以通过插入一对标记/值从其他记录r2生成该记录。因此从某种意义上说:

r1

在这种情况下,r1 + tag/value = r2 Variant

从自述文件中引用

r2

这让我感到困惑。我可以将foo :: forall v. Variant (foo :: Int | v) foo = inj (SProxy :: SProxy "foo") 42 bar :: forall v. Variant (bar :: Boolean | v) bar = inj (SProxy :: SProxy "bar") true fooToString :: forall v. Variant (foo :: Int | v) -> String fooToString = on (SProxy :: SProxy "foo") show (\_ -> "not foo") 作为bar的参数,而从fooToString的类型不能保证它具有标签“ foo”,即使它是开放类型也是如此。这怎么可能?

1 个答案:

答案 0 :(得分:2)

<a href="/shop/productdetail/{{ $productsOT->relevant_id_colunm_name }}" class="card-link">Bekijk hier het product</a> foo都限制变体类型必须包含一些标签,但是它们不会阻止其他标签包含在变体中。应用bar时的具体类型为:

fooToString bar

如您所见,它们完全兼容。


类型的内部版本为

 bar :: Variant (bar :: Boolean, foo :: Int) -- v = (foo :: Int)
 fooToString :: Variant (foo :: Int, bar :: Boolean) -> String -- v = (bar :: Boolean)

将专门研究

bar :: forall r1 r2. RowCons "bar" Boolean r1 r2 => Variant r2
fooToString :: forall r1 r2. RowCons "foo" Int r1 r2 => Variant r2 -> String

bar :: RowCons "bar" Boolean (foo :: Int) (foo :: Int, bar :: Boolean) => Variant (foo :: Int, bar :: Boolean) fooToString :: RowCons "foo" Int (bar :: Boolean) (foo :: Int, bar :: Boolean) => Variant (foo :: Int, bar :: Boolean) -> String 中,bar设置为r1 /专门用于(foo :: Int),而r2成为(foo :: Int, bar :: Boolean)。对于fooToString同样。

如您所见,在bar和fooToString的约束之外,r1未被使用,这使得可以自由选择它们来满足约束。对于编译器来说,向类型中添加更多(未使用的)变体同样有效,但这不会改变结果。


编辑:

与Pruescript不同的是,不仅功能而且值可以是多态的。在这种情况下,bar是一个多态值,fooToString是一个多态函数。这意味着barfooToString的用户可以自由选择v(或r1 / r2)的任何类型,只要该类型包含所需的变体。