haskell - 反射是否有不连贯的风险?

标签 haskell reflection typeclass

reflection包提供了一个类

class Reifies s a | s -> a where
  reflect :: proxy s -> a

和一个函数
reify :: a -> (forall s . Reifies s a => Proxy s -> r) -> r

只考虑这些,一个人可能会因为给出实例而把事情搞得一团糟
instance Reifies s Int where
  reflect _ = 0

这会很糟糕,因为例如,
reify (1 :: Int) $ \p -> reflect p

可以合法地产生 1(通过通常的反射过程)或 0(通过在应用 reify 之前专门化传递的函数)。

实际上,这个特殊的利用似乎被几个 Reifies 所阻止。 Data.Reflection 中的实例.我描述的邪恶实例将被拒绝为重叠。如果启用了重叠实例,我相信特化可能会被重叠带来的不确定性所阻碍。

不过,我想知道是否有某种方法可以通过一个阴暗的实例来揭露这一点,也许是在 GADT 或类似的帮助下。

最佳答案

我试探性地说,它不会冒不连贯的风险。经过一番修补,我能想出劫持 reflect 的最佳方法使用 INCOHERENT ,这不足为奇地足以产生不连贯性:

{-# LANGUAGE
  TypeFamilies, FlexibleInstances, MultiParamTypeClasses,
  ScopedTypeVariables #-}

import Data.Constraint
import Data.Proxy
import Data.Reflection

instance {-# INCOHERENT #-} Reifies (s :: *) Int where
  reflect _ = 0

reflectThis :: forall (s :: *). Dict (Reifies s Int)
reflectThis = Dict

-- prints 0
main = print $
  reify (1 :: Int) $ \(p :: Proxy s) ->
   case reflectThis :: Dict (Reifies s Int) of
     Dict -> reflect p

关于haskell - 反射是否有不连贯的风险?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34708700/

相关文章:

haskell - 我可以避免一遍又一遍地显式派生内置 Haskell 类型类吗?

java - 为什么泛型类型参数上的注释对于嵌套类型不可见?

haskell - 类型类和模块如何交互?

java - 我可以在 Java 中定义 Negatable 接口(interface)吗?

java - 如何调用Method Invoke——反射

haskell - Cabal 安装在构建 Yesod 项目时抛出 ExitFailure 1

haskell - dupTo 与 STDOUT 相关的奇怪现象

linux - cabal-install 安装失败

c# - Reflection.Emit 和 Parallel.ForEach