purescript - 了解纯脚本变体
问题描述
新手来了 我试图了解purescript-variant背后的一些机制。基本上我的意思是如何理解这两个函数:inj和on。
当我查看 的类型时inj
,作者使用了Cons类型类。据我了解,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")
这就是让我感到困惑的地方。我可以将 thebar
作为参数提供给fooToString
while 的类型,bar
即使它是开放类型,也不能保证它具有标签“foo”。这怎么可能?
解决方案
两者都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
。
如您所见,r1 在 bar 和 fooToString 的约束之外未使用,这允许自由选择它们以满足约束。编译器向类型添加更多(未使用的)变体同样有效,但这不会改变结果。
编辑:
Pruescript 的不同寻常之处在于,不仅函数,而且值也可以是多态的。在这种情况下,bar
是一个多态值并且fooToString
是一个多态函数。这意味着两者的用户都bar
可以fooToString
自由选择v
(或r1
/ r2
)的任何类型,只要该类型包含所需的变体即可。
推荐阅读
- javascript - 用户点击提交后不显示提示信息
- android - 使用 LiveData 和 ViewModel 删除项目会导致重新发射
- webview - 仅在完成 javascript 代码后如何显示 WebView?
- java - java - 如何获取今年java已通过月份的列表?
- spring - 嵌入 Apache FTP 服务器:无法同时登录 40 个用户
- sql - 如何在没有主键的表上按顺序更新表?
- javascript - 如何在预加载器完成加载之前隐藏所有正文元素
- javascript - 在 Gridsome 项目 (Vue.js) 中使用 .GLB / Blender 文件
- autohotkey - 您如何在 Autohotkey(AHK) 中转换或缩写数字?(发布由 autohotkey 不和谐组做出的答案)
- php - 如何从 wordpress 中的自定义插件向 php 文件发出获取请求