反思是否存在不连贯性?

时间:2016-01-10 17:43:22

标签: 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或其他一些人的帮助下。

1 个答案:

答案 0 :(得分:4)

我暂时说它没有风险不连贯。经过一些修修补补后,我能用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 ,这不足以让人产生不连贯性:

@Autowired
    private securityUserDetailService securityUserDetailService ;

@Autowired
public void configAuthBuilder(AuthenticationManagerBuilder builder) throws Exception {
    builder.userDetailsService(securityUserDetailService );
}