gpt4 book ai didi

haskell - Vinyl:使用需要所有字段共享约束的函数进行 rtraverse

转载 作者:行者123 更新时间:2023-12-02 15:26:32 24 4
gpt4 key购买 nike

我构建了一个简单的 Vinyl 示例记录。首先,一些语言编译指示和导入:

{-# LANGUAGE DataKinds, TypeOperators #-}

import Data.Vinyl
import Data.Vinyl.Functor
import Control.Applicative

实际示例(为简单起见,它使用 HList 类型同义词):

mytuple :: HList [Integer,Bool]
mytuple = Identity 4 :& Identity True :& RNil

编译成功。但现在我想使用 rtraverse 打印黑胶唱片:

printi :: Show a => Identity a -> IO (Identity a)
printi (Identity x) = print x *> pure (Identity x)

main :: IO ()
main = rtraverse printi mytuple *> pure ()

这会产生以下错误:没有因使用“printi”而产生的 (Show x) 实例。我猜这是预期的,因为 rtraverse 需要一个没有约束的函数。

如何解决这个问题?看起来像reifyConstraint将成为解决方案的一部分,但我不知道如何使用它。

最佳答案

您是对的,reifyConstraint 将解决此问题。该函数的作用是将约束转换(或“具体化”)为数据类型,即 Dict 数据类型。例如

>:t reifyConstraint (Proxy :: Proxy Show) mytuple
(reifyConstraint (Proxy :: Proxy Show) mytuple)
:: Rec (Dict Show :. Identity) '[Integer, Bool]

此记录中的每个元素都将采用 Dict (Identity _) 形式。 Dict 定义为

data Dict c x where Dict :: c x => x -> Dict c x

现在您只需要一个可以处理 (Dict Show :. Identity) a 作为输入的遍历函数。

printi :: Compose (Dict Show) Identity a -> IO (Compose (Dict Show) Identity a) 
printi x@(Compose (Dict a)) = print a >> return x

请注意,您不需要对 a 进行 Show 约束 - Show 类字典存储在 Dict 数据类型。您可以使用此函数进行遍历。

main = rtraverse printi (reifyConstraint (Proxy :: Proxy Show) mytuple)

关于haskell - Vinyl:使用需要所有字段共享约束的函数进行 rtraverse,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29458112/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com