新手在这里。我试图了解purescript-variant背后的一些机制。基本上,我的意思是如何理解这两个功能:inj和on。
当我查看 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”,即使它是开放类型也是如此。这怎么可能?
答案 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
是一个多态函数。这意味着bar
和fooToString
的用户可以自由选择v
(或r1
/ r2
)的任何类型,只要该类型包含所需的变体。