Haskell 如何抽象秩-2型函数中的约束?

Haskell 如何抽象秩-2型函数中的约束?,haskell,typeclass,existential-type,constraint-kinds,Haskell,Typeclass,Existential Type,Constraint Kinds,以下代码片段借用了typeclass字典和存在类型: {-# language ExistentialQuantification #-} module Experiment1 where data Showable = forall x. Show x => Showable x instance Show Showable where showsPrec p (Showable x) = showsPrec p x resultStr :: String resultStr = s

以下代码片段借用了typeclass字典和存在类型:

{-# language ExistentialQuantification #-}
module Experiment1 where

data Showable = forall x. Show x => Showable x
instance Show Showable where showsPrec p (Showable x) = showsPrec p x

resultStr :: String
resultStr = show (Showable ()) -- "()"
是否可以编写一个函数
f::(forall x.x->result)->result
,该函数能够将
可显示的
构造函数(或任何其他存在类型的数据构造函数)作为参数

一次失败的尝试如下所示:

{-# language ExistentialQuantification, RankNTypes, ConstraintKinds #-}

module Experiment2 where

-- import Data.Constraint (Dict(..), withDict)

data Showable = forall x. Show x => Showable x
instance Show Showable where showsPrec p (Showable x) = showsPrec p x

f :: (cxt (), cxt result) => (forall x. cxt x => x -> result) -> result
f mkResult = mkResult ()

resultStr :: String
resultStr = show (f Showable)

正如我上面评论的导入所暗示的那样,我的印象是,该软件包可能允许我传递必要的证据,但我看不出这将如何工作?

如果您提供一种方法来确定
cxt

import Data.Proxy

f :: (cxt (), cxt result) => p cxt -> (forall x. cxt x => x -> result) -> result
f _ mkResult = mkResult ()

resultStr :: String
resultStr = show (f (Proxy :: Proxy Show) Showable)

我很抱歉发布了我自己的答案,但这是我最终发现的另一个选择:

{-# language ExistentialQuantification, RankNTypes, ConstraintKinds, KindSignatures, TypeFamilies, FlexibleInstances #-}

module Experiment3 where

import GHC.Exts

data Showable (cxt :: * -> Constraint) = forall x. (cxt ~ Show, cxt x) => Showable x
instance Show (Showable Show) where showsPrec p (Showable x) = showsPrec p x

f :: cxt () => (forall x. cxt x => x -> result cxt) -> result cxt
f mkResult = mkResult ()

resultStr :: String
resultStr = show (f Showable :: Showable Show)
不幸的是,它在
show(f Showable)
中需要一个显式的类型签名,而我的目标是通过
Showable
获得类型推断(或者更确切地说,某种约束推断)。所以这个答案本身并不是一个解决方案,而是我想要的另一个反例


我将接受Cirdec的回答,因为它引导我得出了这个结论。

你希望编译器如何从类型
结果中确定约束
cxt
是什么?好的,我试图从
mkResult
中推断约束,但当然没有办法这样做。现在看看它,我想我试图以某种方式为所有x定义
datashowable(cxt~Show)=。cxt x=>Showable x
这样
f:(cxt(),cxt(result cxt))=>(对于所有x.cxt x=>x->result cxt)->结果cxt
并直接从
Showable
f::对于所有cxt进行推断。(cxt(),cxt结果)=>(对于所有x.cxt x=>x->result)->结果
,然后使用
-XTypeApplications