用`Proxy s`绑定类型与用forall绑定类型

尼古拉斯

在下面的示例中,我不清楚为什么toto会失败,但是tata会起作用。

有什么解释吗?

{-# LANGUAGE AllowAmbiguousTypes  #-}
{-# LANGUAGE  TypeFamilies, KindSignatures, FlexibleContexts #-}
{-# LANGUAGE TypeApplications, FunctionalDependencies, MultiParamTypeClasses #-}
{-# LANGUAGE ScopedTypeVariables , GADTs, MultiParamTypeClasses, RankNTypes                #-}
{-# LANGUAGE TypeOperators, UnicodeSyntax, DataKinds              #-}

import Data.Proxy

data KNat where
class ReflectNum (s :: KNat) where

toto ∷ (∀ (s :: KNat). ReflectNum s ⇒ Int) → Int
toto k = toto k

tata ∷ (∀ (s :: KNat). ReflectNum s ⇒ Proxy s -> Int) → Int
tata k = tata (\(p :: Proxy s) -> k p)

错误正在

SO.hs:14:15: error:
    • Could not deduce (ReflectNum s0) arising from a use of ‘k’
      from the context: ReflectNum s
        bound by a type expected by the context:
                   forall (s :: KNat). ReflectNum s => Int
        at SO.hs:14:10-15
      The type variable ‘s0’ is ambiguous
    • In the first argument of ‘toto’, namely ‘k’
      In the expression: toto k
      In an equation for ‘toto’: toto k = toto k
   |
14 | toto k = toto k
   |               ^
亚历克西斯·金

这是GHC实施可见类型应用程序的已知限制。具体来说,Proxy有时仍然需要使较高级别的函数(例如您的toto函数)的参数访问类型变量。

有一个GHC建议以lambda-expressions中类型变量绑定的形式为该问题添加解决方案使用提案中的语法,您的toto函数可以编写为

toto k = toto (\@s -> k @s)

本地绑定s变量。遗憾的是,该建议尚未实施。

同时,对于此类高级功能,我认为您只需要使用即可Proxy抱歉。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章