问题标签 [phantom-types]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
1 回答
89 浏览

haskell - 消除列表中的幻像类型

我在弄清楚如何在列表中的 ST monad 中运行计算时遇到了一些麻烦。

但是尝试编译它会出现以下错误:

如果我在 IO monad 中运行它,这将是一个简单的替换pure . map runSTtraverse runIO(或其他)的问题,但我还没有弄清楚如何绕过幻像类型参数的存在。我怀疑该列表sts需要为不同的列表元素具有不同的类型参数,因此需要是具有某种说服力的异构列表,但是包装 ST 单子只会引入旧错误之外的新错误。

处理此问题的最佳方法是什么,其中幻像类型变量被函数消除runST,因此应该是统一的,但我无法说服类型检查器?

注意:我试图弄清楚的实际示例涉及inline-r包中的 R monad,它也有一个幻像类型,并用 function 消除runRegion :: NFData a => (forall s. R s a) -> IO a。我相信 ST monad 中的这个例子也应该抓住这里的根本问题,并且更广为人知。

0 投票
0 回答
40 浏览

haskell - 使用 QuickCheck 将 ST 与多态测试“模板”一起使用

我有一个具有关联单子的类,以便可以为不同的单子创建实例。

我想用QuickCheck.

我想创建代表“法律”的函数,如下所示:

TestHarness是辅助函数的元组:

为测试提供要使用的“Ref”,并将动作Property分别转换为 a。

然后,我将能够使用“法律”和线束来实例化 QuickCheck 测试属性。

对于IO,这没有问题:

编译并运行。

但是,我也有一个ST例子:

然而,试图天真地定义一个测试工具,

失败并显示错误消息:

我猜我需要在某个地方进行量化,但我还没有通过反复试验成功地确定哪里。

是否可以ST像这样参数化我的线束类型?

我该如何去做我想做的事?

0 投票
0 回答
45 浏览

haskell - 了解ST的量化和幻型

我正在尝试使用Test.QuickCheck.Monadic.

该模块提供了一个线束

执行ST-based 测试和一个函数

将任何动作提升到测试单子中。

在我的代码中,我有一个多态单子动作:

以下函数

编译失败:

但是这个

编译没有问题。

谁能解释一下?

0 投票
3 回答
826 浏览

haskell - Haskell 的“Const”函子是否类似于范畴论中的常数函子?

我知道 Haskell 中的许多名称都受到范畴论术语的启发,我试图准确理解类比的开始和结束位置。

类别Hask

由于一些关于严格/懒惰和的技术细节,我已经知道这Hask不是(必然)一个类别seq,但现在让我们把它放在一边。为了清楚起见,

  • 的对象Hask是具体的类型,即 kind 的类型*。这包括函数类型Int -> [Char],但不包括任何需要类型参数的东西,如Maybe :: * -> *. 但是,具体类型Maybe Int :: *属于Hask。类型构造函数/多态函数更像是自然转换(或其他更一般的从Hask自身到自身的映射),而不是态射。
  • 的态射Hask是 Haskell 函数。对于两个具体类型AB,hom 集Hom(A,B)是具有签名的函数集A -> B
  • 函数组合由 给出f . g。如果我们担心严格性,我们可能会将组合重新定义为严格,或者在定义函数的等价类时要小心。

Functors 是内函子Hask

我认为上面的技术细节与我在下面的困惑没有任何关系。我想我理解它的意思是说每个实例Functor都是 category 中的一个 endofunctorHask。也就是说,如果我们有

Functor实例以下列方式Maybe对应于一个仿函数 from Haskto :Hask

  • 对于 中的每个具体类型aHask我们分配具体类型Maybe a

  • 对于 中的每个态射f :: A -> BHask我们分配Maybe A -> Maybe B发送Nothing ↦ Nothing和的态射Just x ↦ Just (f x)

常数(endo)函子

类别 C 上的常量(endo)函子是一个函子,将类别 C 的Δc : C → C每个对象映射到固定对象c∈C,并将 C 的每个态射映射到固定对象的恒等态射id_c : c → c

Const Functor

考虑Data.Functor.Const。为了清楚起见,我将在这里重新定义它,区分类型构造函数Konst :: * -> * -> *和数据构造函数Const :: forall a,b. a -> Konst a b

这种类型检查是因为数据构造函数Const是多态的:

我可以买那Konst m是该类别中的一个内函子Hask,因为在 implmenetation 中fmap

  • 在左侧,Const v表现为 a Konst m a,由于多态性,这是可以的
  • 在右侧,Const v显示为 a Konst m b,由于多态性,这是可以的

但是,如果我们试图将其Konst m :: * -> *视为范畴论意义上的常数函子,我的理解就会崩溃。

  • 什么是固定对象?类型构造函数Konst m接受一些具体类型a并给我们一个Konst m a,至少从表面上看,它是每个 不同的具体类型a。我们真的想将每种类型映射a到固定类型m

  • 根据类型签名,fmap接受一个f :: a -> b并给我们一个Konst m a -> Konst m b. 如果Konst m类似于常量函子,则fmap需要将每个态射发送到id :: m -> m固定类型上的恒等态射m

问题

所以,这是我的问题:

  1. Haskell 的Const函子在哪些方面类似于范畴论中的常数函子(如果有的话)?

  2. 如果这两个概念不等价,甚至有可能SimpleConst在 Haskell 代码中表达范畴论常数函子(比如说)?我快速尝试了一下,并遇到了与上述幻象类型的多态性相同的问题:

  1. 如果#2 的答案是肯定的,如果是,那么在范畴论意义上,这两个 Haskell 函数有什么关系?也就是说,在 Haskell 中的SimpleConstto就像在范畴论中Const的常量函子一样?__?__

  2. Hask幻像类型是否会像类别一样思考问题?我们是否需要修改 的定义,Hask使对象真正成为类型的等价类,如果没有幻像类型参数,这些类型本来是相同的?

编辑:自然同构?

看起来多态函数是从函子到常量函子getConst :: forall a,b. Konst a b -> a的自然同构的候选者,尽管我还不能确定后者是否可以在 Haskell 代码中表达。η : (Konst m) ⇒ ΔmKonst mΔm : Hask → Hask

自然转化法则就是η_x = (Konst m f) . η_y。我无法证明这一点,因为我不确定如何正式推理 a(Const v)从 typeKonst m a到的转换Konst m b,除了挥手说“存在双射!”。

相关参考

以下是上面尚未链接的可能相关问题/参考的列表:

0 投票
2 回答
150 浏览

rust - 使用特征作为幻像类型

在 Rust 中,我想使用幻像类型来正确键入一个简单的 id:

在第一个草稿版本中,我使用了具体的结构T,一切都很好。然后在使用不同数据源的更精细的版本中,这些结构变成了特征。比方说:

但是使用traits作为幻像类型会带来问题:

  • 编译器让我声明T: ?Sized,好像T是可能需要的大小。我可以忍受,但由于目的PhantomData<T>是告诉它T不会被使用,我想知道是否还有其他方法?
  • 我收到警告:“不推荐使用没有明确 'dyn' 的特征对象”。我可以用 global 摆脱它#![allow(bare_trait_objects)],但是这个警告在其他方面很有用,我不想这样做。有没有办法bare_trait_object 允许“当用作”的类型参数时Id<T>

我当前的解决方案是在空结构和特征之间复制名称类型:

这很尴尬,但我找不到更好的。

0 投票
1 回答
98 浏览

scala - 未强制执行的方法的类型限制

我无法理解为什么编译器允许当前代码。

我使用幻像类型来保护对方法的访问。只有在特定的“状态”下才允许调用方法。

在大多数情况下,这个不变量确实是经过编译验证的。然而,有时编译器只是忽略了幻像类型所施加的约束。这感觉像是一个重大错误。我不明白什么?

我试图尽可能地简化问题。我的用例更复杂:

然后

正如您在上面看到的,客户端可以关闭一扇关闭的门。在我的库中,相应的行为是抛出运行时异常。(我确信异常得到了很好的保护并且无法访问)

我只能为返回布尔值的表达式复制此问题,并且当这是函数的参数时(在示例中,println

我不是在寻找替代解决方案,而是在寻找关于如何发生这种情况的解释?你不同意这是一个相当大的缺陷吗?或者,也许我错过了什么?

Scala version: 2.13.5

编辑
在讨论了gitter之后,我打开了错误请求@https ://github.com/scala/bug
问题似乎没有出现在 scala 3 中。

0 投票
0 回答
137 浏览

typescript - 打字稿可以在运行时检索幻像类型参数吗?

我正在使用一个非常复杂的 API,并且某些字段是限制性字符串(长度为 X 最大值的字符串)。所以我创建了这种类型:

它可以很好地创建具有我想要的格式的字符串,但是有交易,我必须用这种类型填充一个对象,但是每个键的最大长度可以不同,我需要知道要写的最大长度是多少在对象的关键。示例:

如果有人知道如何处理它,非常感谢!:)

0 投票
0 回答
39 浏览

haskell - `type` 与 phantom 的同义词不允许出现警告?

b被称为“幻影类型”,因为它不会出现在=. 这对于数据的类型级标记很有用。

(GHC 不抱怨,即使有:set -Wall。)b是什么?它有什么用处?

我觉得 GHC 应该警告我b没有在 RHS 上使用。

0 投票
1 回答
142 浏览

typescript - 如何使幻像类型与 TypeScript 中的方法一起使用?

考虑以下使用幻像类型的程序:

操场

上述程序类型检查是因为推断出正确的类型。该constant值具有推断类型Const<boolean, never>。该函数以、和map类型调用。该函数以、和类型调用。A = booleanB = stringC = numbercontramapA = booleanB = numberC = string

但是,使用方法而不是函数来编写上述表达式会很好。因此,我尝试了以下方法:

操场

如您所见,该map方法有效,但该contramap方法无效。这是因为 is 的类型constant并且Const<boolean, never>它没有被方法调用细化,即 formap类型没有被细化到Const<boolean, string>并且contramap类型没有被细化到Const<boolean, number>

正因为如此,要么工作map要么contramap工作,但不能同时工作。如果对象的类型是Const<boolean, never>contramap不起作用。如果对象的类型是Const<boolean, unknown>map不起作用。

我怎样才能同时map使用contramap方法而不是函数来工作?

0 投票
1 回答
123 浏览

haskell - Convert Sum Type to Phantom Type via Type Classes

I was experimenting with phantom types in Haskell. My goal is to convert the LangCode Type to it's corresponding Phantom Type representation via Type Classes for example DE to Lang DE.

With a type annotation it works fine. But without it I get this error.

My question is. Is it possible to implement it in a way so that the type annotations are no longer needed?

Updated version