- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
所以这是我的对象系统传奇的延续(part 1,part 2)。
这部分基本上归结为以下内容。
{-# LANGUAGE ExistentialQuantification #-}
{-# LANGUAGE ConstraintKinds #-}
{-# LANGUAGE KindSignatures #-}
import Data.Typeable
import GHC.Exts (Constraint)
data Obj (cls :: * -> Constraint) = forall o. (cls o, Typeable o) => Obj o
downcast :: Obj a -> Maybe (Obj b)
downcast (Obj x) = do
cx <- cast x
return $ Obj cx
downcast
的定义失败并出现此错误:
• Could not deduce: b o0 arising from a use of ‘Obj’
from the context: (a o, Typeable o)
bound by a pattern with constructor:
Obj :: forall (cls :: * -> Constraint) o.
(cls o, Typeable o) =>
o -> Obj cls,
in an equation for ‘downcast’
at downcast.hs:12:11-15
• In the second argument of ‘($)’, namely ‘Obj cx’
In a stmt of a 'do' block: return $ Obj cx
In the expression:
do cx <- cast x
return $ Obj cx
• Relevant bindings include
cx :: o0 (bound at moo.hs:13:22)
downcast :: Obj a -> Maybe (Obj b) (bound at downcast.hs:12:1)
我不太明白为什么会出现这个错误:( 可以修复吗?
最佳答案
当您的 Haskell 被翻译成 GHC Core 时,类(以及随之而来的逻辑编程构造,如蕴涵)已经无处可寻。它们被编译器转换为字典传递代码——每个实例
成为一个记录(一个常规值)并且每个方法成为该记录的一个成员。 (有关更多细节,请参阅 a previous answer of mine。)
所以一个打包约束的构造函数,
data Obj c where -- I'm using GADT syntax
Obj :: c a => a -> Obj c
在运行时确实由常规产品类型表示,
data Obj c where
Obj :: c a -> a -> Obj c
其中 c a
字段是表示 c a
实例的运行时方法字典。
在运行时将 Obj c
向下转换为 Obj c'
,即使您有办法测试具体的 a
是c
和 c'
的实例,您仍然需要以某种方式为 c'
合成字典。由于 c'
通常包含比 c
更多的方法,这相当于要求计算机为您编写程序。
As David mentioned in the comments ,我认为您最好的选择是在封闭世界的假设下将有关特定类层次结构的知识构建到您的运行时系统中。如果你有一个可以查询实例实际运行时间的 oracle dictionary ,
oracle :: MonadRuntime m => TypeRep a -> TypeRep c -> m (Maybe (Dict (c a)))
然后你可以写cast
(有一些不舒服的类型争论):
data Obj c where
Obj :: c a => TypeRep a -> a -> Obj c
cast :: forall c c' m. (MonadRuntime m, Typeable c') => Obj c -> m (Maybe (Obj c'))
cast (Obj tr x) = do
mdict <- oracle tr (typeRep @c')
case mdict of
Just Dict -> return (Just (Obj tr x))
Nothing -> return Nothing
请注意,此cast
实际上允许您(尝试)将对象的接口(interface)更改为任何 其他接口(interface),而不仅仅是那些从对象的静态类型派生的接口(interface)。 (在 C# 中,您可以通过向上转换为 object
然后向下转换来执行此操作。)您可以通过要求 entailment 来防止这种情况发生。在 cast
的上下文中:
cast :: forall c c' m. (MonadRuntime m, Typeable c', Class c c') => Obj c -> m (Maybe (Obj c'))
(当然,这个蕴涵实际上不会在运行时使用。)
挑战在于实现oracle
!我认为这将是那些不好玩的挑战之一,所以我只会给你一两点建议。
您的Runtime
monad 可能是某种Reader
,带有查找表映射(TypeRep
)a
s 和 c
到字典。 a
和 c
需要进行存在量化,以便将它们存储在异构列表中。
data TableEntry where
TableEntry :: c a => TypeRep c -> TypeRep a -> TableEntry
type MonadRuntime = MonadReader [TableEntry]
然后oracle
需要查找匹配类/类型对的TableEntry
,然后打开existential,通过拆开typeRep建立类型相等
s,并返回 Just Dict
。 (特别是这部分听起来像是编写代码的噩梦。)
在运行 MonadRuntime
程序之前,您需要构建包含程序关心的所有实例的 Table
。
table = [
TableEntry (typeRep @Ord) (typeRep @Int),
TableEntry (typeRep @Eq) (typeRep @Bool)
]
总而言之,我不明白这有什么值得头疼的。类型类从根本上不同于 OO 类(它们甚至不太像 OO 接口(interface)),因此很难使用它们来为 OO 类建模也就不足为奇了。
关于haskell - Data.Typeable.cast 到现有类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62699440/
假设我有以下代码: {-# LANGUAGE GADTs, DeriveDataTypeable, StandaloneDeriving #-} import Data.Typeable class
我正在尝试为关联的数据系列派生Typeable,如下所示: {-# LANGUAGE DeriveDataTypeable #-} {-# LANGUAGE TypeFamilies #-} modu
如何为 Typeable 编写实际的实例声明?例如,假设我想为 Char 编写一个实例,其中每个字符都有不同的类型,例如 instance Typeable Char where typeOf
[...] wants to find all the places in a legacy codebase that a variable foo is used in the condition
我大致想要实现以下目标: f :: a -> a g :: b -> b h :: Typeable t => t -> Maybe t h x = case x of (x is of type
例如,假设我们有以下数据结构: data Foo = Bool Bool | Int Int | Double Double 现在,有没有更简单的方法来做到这一点: foo :: Typeable a
所以这是我的对象系统传奇的延续(part 1,part 2)。 这部分基本上归结为以下内容。 {-# LANGUAGE ExistentialQuantification #-} {-# LANGUA
通用编程时间! 如果我有一个函数: f :: a1 -> a2 -> a3 -> ... -> an 和一个值 v :: aX -- where 1 a2 -> a3 -> a4 -> a5)
自 GHC 7.8 起,Typeable 是多类的。查看内置 Typeable 实例列表 in the documentation ,我注意到一些有趣的事情: Typeable ((* -> *) -
我遇到过对 Haskell 的 Data.Typeable 的引用,但我不清楚为什么要在代码中使用它。 它解决了什么问题以及如何解决? 最佳答案 Data.Typeable 是一种众所周知的方法(参见
我正在玩 Haskell 的 Data和 Typeable ,并且我一直试图在上下文中没有可用类型变量的情况下获取函数的参数。 让我澄清一下我的意思。只要我像下面这样对类型变量 a 进行量化,我就可以
有人能给我指出一组在 Haskell 中为 GADT 定义 Typeable 或 Typeable1 实例的好示例吗? 或者,有人可以向我展示如何为以下 GADT 定义 Typeable(手动)。 d
我有一些这样的类型: data Currency = USD | EUR deriving (Show, Typeable) data Money :: Currency
我正在尝试为 (':) 派生一个 Typeable 实例 我正在使用 DataKinds 和 [*]。 我启用了 TypeOperators、StandaloneDeriving 和 PolyKind
我有 data D t = ... data SomeStuff = forall a (Typeable a, ...) => SomeStuff a 在某些时候,我得到了一个 SomeStuff,
我试图使用 Shapeless Typeable 来使对 Java 库的访问更加类型安全,但遇到了障碍。我不确定我是否滥用了该库,是否必须手动提供类型类实例,或者是否有其他问题。 此代码演示了我的问题
我是一名优秀的程序员,十分优秀!