【问题标题】:Existential quantification of typeclass constraints类型类约束的存在量化
【发布时间】:2017-11-07 14:52:32
【问题描述】:

我不确定为什么 ko 不进行类型检查。 有没有特别有启发性的解释?

{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE NoMonomorphismRestriction, FlexibleInstances #-}

module Wrap where

class ExpSYM repr where
    lit :: Int -> repr

newtype Wrapped = Wrapped{unWrap :: forall repr. ExpSYM repr => repr}

a = (lit <$> Just 5) :: ExpSYM expr => Maybe expr

ko :: Maybe Wrapped
ko = do v <- a
        return $ Wrapped $ v

ok :: Maybe Wrapped
ok = do v <- Just 5
        let e = lit v
        return $ Wrapped $ e

编译器提到

SO.hs:15:14: error:
    • No instance for (ExpSYM a0) arising from a use of ‘a’
    • In a stmt of a 'do' block: v <- a
      In the expression:
        do { v <- a;
             return $ Wrapped $ v }
      In an equation for ‘ko’:
          ko
            = do { v <- a;
                   return $ Wrapped $ v }

SO.hs:16:28: error:
    • Couldn't match expected type ‘repr’ with actual type ‘a0’
        because type variable ‘repr’ would escape its scope
      This (rigid, skolem) type variable is bound by
        a type expected by the context:
          ExpSYM repr => repr
        at SO.hs:16:18-28
    • In the second argument of ‘($)’, namely ‘v’
      In the second argument of ‘($)’, namely ‘Wrapped $ v’
      In a stmt of a 'do' block: return $ Wrapped $ v
    • Relevant bindings include v :: a0 (bound at SO.hs:15:9)
Failed, modules loaded: none.

编辑: 在 Oleg 的笔记中找到了一个很好的解决方案来规避这个问题,即专门化类型,以便通过类型应用程序删除多态性,添加实例

instance ExpSYM Wrapped where
   lit x = Wrapped $ lit x

然后我们有

notko :: Maybe Wrapped
notko = do v <- a    
           return $ v -- note the difference. what's the type of a ?

-- and we get all the usual goodies, no silly impredicative error
alsoOk = lit <$> Just 5 :: Maybe Wrapped

【问题讨论】:

  • 不起作用”是什么意思。请提供编译错误/意外输出等。
  • 我的意思当然是类型检查。每个人都知道在类型检查之后,一切正常;) - (虽然你是对的)
  • 该错误表明 newtype 已经出错,而不是 ko/ok

标签: haskell typeclass quantifiers


【解决方案1】:

ko 仅在 a 的类型为时才有效

a :: Maybe (∀ expr . ExpSYM expr => expr)
a = lit <$> Just 5

...因为只有这样你才能解开它以获得多态值v :: ∀ expr . ExpSYM expr =&gt; expr。该值必须是多态的,因此它实际上可以在Wrapped 中使用。

但是Maybe (∀ expr . ExpSYM expr =&gt; expr)impredicative type。 GHC Haskell 不支持隐含类型。

OTOH,okv 只是一个无聊的旧整数,来自一个不起眼的 Just 5 :: Maybe Int。只有e 引入了多态性,但在Maybe monad 之外这样做。

【讨论】:

  • 正确。谢谢你。所以多态性应该排在最后。我有另一个非常反直觉的例子,其中从连续应用 g 切换到 f 应用到某些值是有效的,而首先组合函数并应用于值失败。有点郁闷..
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-01-21
  • 2012-09-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-01-06
相关资源
最近更新 更多