首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何使用Rank-2类型抽象函数中的约束?

如何使用Rank-2类型抽象函数中的约束?
EN

Stack Overflow用户
提问于 2018-01-03 09:58:20
回答 2查看 90关注 0票数 1

下面的代码片段从the Haskell wiki借用来携带一个类型类字典和一个存在类型:

代码语言:javascript
复制
{-# 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 ()) -- "()"

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

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

代码语言:javascript
复制
{-# 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)

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

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-01-03 11:43:41

如果您提供了一种确定cxt的方法,则失败的尝试将起作用

代码语言:javascript
复制
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)
票数 1
EN

Stack Overflow用户

发布于 2018-01-03 13:42:39

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

代码语言:javascript
复制
{-# 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的回答,因为它引导我得出这个结论。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/48070211

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档