类型级别的唯一符号值
Unique symbol value on type level
是否可以在类型级别上有某种唯一的符号值,可用于区分(标记)某些记录而不需要提供唯一的字符串值?
在JS中有Symbol经常用于这样的事情。但是我想在纯上下文中不使用 Effect 就拥有它。
好吧,它甚至可能喜欢访问完全限定的模块名称(这对于任务来说是非常独特的),但我不确定这是否真的是 relevant/possible 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的状态的,它传递给worker的值和当前状态值,得到新状态值的Effect,放入state map中,key是tags。
模块的用户:
在一个模块中:
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”)作为标签而是使用一些“生成的”唯一值,那就太好了。但是任务是应该在纯上下文中在模块的顶层创建worker。
PureScript 的语义本身是纯粹的,与这类事情几乎不兼容。相同的表达式总是产生相同的结果。结果可以在较低级别以不同方式表示,但在语言语义中它们是相同的。
这是一个功能,不是错误。根据我的经验,通常情况下,像您这样的要求表明上游某处存在设计缺陷。
此规则的一个例外是 FFI:如果您必须与底层平台交互,则别无选择,只能遵守该平台的规则。我可以举的一个例子是 React,它使用 JavaScript 的隐式对象身份作为区分组件的一种方式。
所以底线是:我敦促您重新考虑该要求。很有可能,您 真的 不需要它。即使您这样做,手动指定的字符串实际上可能比自动生成的字符串更好,因为它们可能会帮助您稍后进行故障排除。
但如果你真的坚持这样做,好消息:你可以作弊! :-)
您可以有效地生成您的 ID,然后将它们包装在 unsafePerformEffect
中,使其在编译器看来是纯净的。例如:
import Effect.Unsafe (unsafePerformEffect)
import Data.UUID (toString, genUUID)
workerTag :: String
workerTag = toString $ unsafePerformEffect genUUID
是否可以在类型级别上有某种唯一的符号值,可用于区分(标记)某些记录而不需要提供唯一的字符串值?
在JS中有Symbol经常用于这样的事情。但是我想在纯上下文中不使用 Effect 就拥有它。
好吧,它甚至可能喜欢访问完全限定的模块名称(这对于任务来说是非常独特的),但我不确定这是否真的是 relevant/possible 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的状态的,它传递给worker的值和当前状态值,得到新状态值的Effect,放入state map中,key是tags。
模块的用户:
在一个模块中:
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”)作为标签而是使用一些“生成的”唯一值,那就太好了。但是任务是应该在纯上下文中在模块的顶层创建worker。
PureScript 的语义本身是纯粹的,与这类事情几乎不兼容。相同的表达式总是产生相同的结果。结果可以在较低级别以不同方式表示,但在语言语义中它们是相同的。
这是一个功能,不是错误。根据我的经验,通常情况下,像您这样的要求表明上游某处存在设计缺陷。
此规则的一个例外是 FFI:如果您必须与底层平台交互,则别无选择,只能遵守该平台的规则。我可以举的一个例子是 React,它使用 JavaScript 的隐式对象身份作为区分组件的一种方式。
所以底线是:我敦促您重新考虑该要求。很有可能,您 真的 不需要它。即使您这样做,手动指定的字符串实际上可能比自动生成的字符串更好,因为它们可能会帮助您稍后进行故障排除。
但如果你真的坚持这样做,好消息:你可以作弊! :-)
您可以有效地生成您的 ID,然后将它们包装在 unsafePerformEffect
中,使其在编译器看来是纯净的。例如:
import Effect.Unsafe (unsafePerformEffect)
import Data.UUID (toString, genUUID)
workerTag :: String
workerTag = toString $ unsafePerformEffect genUUID