微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

类型级别的唯一符号值

如何解决类型级别的唯一符号值

是否有可能在类型级别拥有某种唯一的符号值,它可以用于区分(标记)某些记录而无需提供唯一的字符串值?

在 JS 中,Symbol 经常用于这样的事情。但我希望在不使用 Effect 的情况下,在纯上下文中使用它。

好吧,它甚至可能喜欢访问完全限定的模块名称(这对于任务来说非常独特),但我不确定这在 PureScript 上下文中是否真的相关/可能。

示例:

说有一些模块暴露:


type Worker value state = 
  { tag :: String,work :: value -> state -> Effect state
  }


makeWorker :: forall value state. Worker value state


performWork :: forall value state. woker -> Worker value state -> value -> Unit

该模块用于管理worker的状态,它传递给他们值和当前状态值,并用新的状态值获取Effect,并放入key为标签的状态映射中。

模块的用户

一个模块中:


worker = makeWorker { tag: "WorkerOne",work }

-- Then this tagged `worker` is used to performWork:
-- performWork worker "Some value"

在另一个模块中,我们使用带有另一个标签的 worker:

worker = makeWorker { tag: "WorkerTwo",work }

因此,如果不需要提供唯一字符串(“WorkerOne”、“WorkerTwo”)作为标签,而是使用一些“生成的”唯一值,那就太好了。但任务是应该在纯上下文中在模块的顶层创建工作线程。

解决方法

PureScript 的语义本身就是纯粹的,并且与此类事物几乎不兼容。相同的表达式总是产生相同的结果。结果可以在较低级别以不同的方式表示,但在语言语义上它们是相同的。

这是一项功能,而不是错误。根据我的经验,像您这样的要求通常表明上游某处存在有缺陷的设计。

此规则的一个例外是 FFI:如果您必须与底层平台交互,则别无选择,只能遵守该平台的规则。我可以举的一个例子是 React,它使用 JavaScript 的隐式对象标识作为区分组件的一种方式。

所以最重要的是:我敦促您重新考虑要求。很有可能,您真的不需要它。即使您这样做了,手动指定的字符串实际上可能比自动生成的字符串更好,因为它们可以帮助您稍后进行故障排除。

但如果你真的坚持这样做,好消息是:你可以作弊! :-)

您可以有效地生成您的 ID,然后将它们包装在 unsafePerformEffect 中,使其对编译器来说看起来很纯粹。例如:

import Effect.Unsafe (unsafePerformEffect)
import Data.UUID (toString,genUUID)

workerTag :: String
workerTag = toString $ unsafePerformEffect genUUID

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。