如何在Haskell中安全地对种类受限的类型变量进行装箱? 问题:

如何在Haskell中安全地对种类受限的类型变量进行装箱? 问题:,haskell,types,Haskell,Types,我想对一个类型变量进行案例分析,由于种类限制,该类型变量的可能性有限。我想静态地知道,套管总是会发现这些有限的可能性之一。我想不出如果没有一个无法达到的通病,如何写这个案例 作为一个具体的例子,假设我有一个数据类型 data{-kind-} Temp = Hot | Cold 然后,我的目标是编写一个函数,如下面的castemp,它确定给定的Temp类型。差不多 data CaseTemp (t :: Temp) where IsHot :: CaseTemp 'Hot IsCold

我想对一个类型变量进行案例分析,由于种类限制,该类型变量的可能性有限。我想静态地知道,套管总是会发现这些有限的可能性之一。我想不出如果没有一个无法达到的通病,如何写这个案例

作为一个具体的例子,假设我有一个数据类型

data{-kind-} Temp = Hot | Cold
然后,我的目标是编写一个函数,如下面的
castemp
,它确定给定的
Temp
类型。差不多

data CaseTemp (t :: Temp) where
  IsHot :: CaseTemp 'Hot
  IsCold :: CaseTemp 'Cold

caseTemp :: forall (t :: Temp). CaseTemp t
caseTemp = ???
我可以对
caseTemp
进行一些额外的限制,比如下面失败的尝试中的
Typeable t
。甚至是用一种完全不同的方法

解决方案尝试失败 这是我最好的尝试,但它包含了一个我认为无法访问的分支,如果我在
Temp
中添加另一个构造函数(在GHC 8.0.2中测试),它将允许
caseTemp
以静默方式中断:

此尝试的问题是GHC认为
Nothing->error“Unreachable!”
分支是可访问的

更新 User@Alec提到
Any::Temp
是我不可能做我想做的事情的一个根本原因,因为

import GHC.Prim ( Any )
[...]
badCase :: CaseTemp Any
badCase = undefined :: CaseTemp Any

已被GHC接受。然而,
Any
是不可
Typeable
的,所以我不清楚对
caseTemp
施加约束不能解决这个问题。

没有直接的方法,因为当
eqT
返回
Nothing
时,它没有质量证明

使用类型类怎么样

class IsTemp (b :: Temp) where
  caseTemp :: CaseTemp b

没有直接的方法,因为当
eqT
返回
Nothing
时,它没有质量证明

使用类型类怎么样

class IsTemp (b :: Temp) where
  caseTemp :: CaseTemp b

这是因为
Any::Temp
@Alec,谢谢,我不知道
Any
。我用一个例子更新了这个问题,说明了我认为你的意思。你对约束的评论很贴切。我鼓励您查看
单身人士
。它还使用约束来回避这类问题。此外,这正是下面给您的答案。:)这是因为
Any::Temp
@Alec,谢谢,我不知道
Any
。我用一个例子更新了这个问题,说明了我认为你的意思。你对约束的评论很贴切。我鼓励您查看
单身人士
。它还使用约束来回避这类问题。此外,这正是下面给您的答案。:)我更新了问题,明确表示我不在乎解决方案是如何实现的。我的代码只是一个不起作用的例子;不需要使用
eqT
。那么,你是在建议我对所有我想装箱的
t::Temp
设置一个
IsTemp t
约束?这可能是可行的……事实上,类型类是使值依赖于类型的标准方法。我更新了问题,以明确我不关心解决方案是如何实现的。我的代码只是一个不起作用的例子;不需要使用
eqT
。那么,你是在建议我对所有我想装箱的
t::Temp
设置一个
IsTemp t
约束?这可能是可行的……事实上,类型类是使值依赖于类型的标准方法。