gpt4 book ai didi

haskell - 实例未导出?

转载 作者:行者123 更新时间:2023-12-03 07:06:08 25 4
gpt4 key购买 nike

我正在尝试将元组转换为HList.Record,但有一些非常奇怪的事情。我创建了一个 ToRecord 类,它将一个事物元组和一个标签元组压缩到一条记录中。一切都可以编译,但实例似乎消失了。当我尝试使用它们时,GHC 提示我要求的实例不存在。

{-# LANGUAGE TypeFamilies, DataKinds, TypeOperators #-}
{-# LANGUAGE MultiParamTypeClasses, FlexibleInstances #-}

-- standard
import GHC.TypeLits (Symbol)
-- third-party
import Data.HList.FakePrelude
import Data.HList.Record
import Data.HList.Labelable
-- local

-- * Tuples <-> Records Conversion
class ToRecord a b where
type Result a b :: *
toRecord :: a -> b -> Result a b -- Result a b

instance ToRecord (Label t1, Label t2) (v1, v2) where
type Result (Label t1, Label t2) (v1, v2) = Record '[Tagged (t1) v1, Tagged (t2) v2]
toRecord (t1, t2) (v1, v2) = t1 .=. v1 .*. t2 .=. v2 .*. emptyRecord

instance ToRecord (Label t1, Label t2, Label t3) (v1, v2, v3) where
type Result (Label t1, Label t2, Label t3) (v1, v2, v3) =
Record '[Tagged (t1) v1, Tagged (t2) v2, Tagged t3 v3]
toRecord (t1, t2, t3) (v1, v2, v3) = t1 .=. v1 .*. t2 .=. v2 .*. t3 .=. v3 .*. emptyRecord

-- dummy instance to check GHC behavior
instance ToRecord Char Integer where
type Result Char Integer = (Char, Integer)
toRecord c i = (c, i)

value = Label :: Label "value"
name = Label :: Label "name"

test = toRecord (value, name) (5 :: Int, "age")

错误消息:

 Utils.hs:34:8:
No instance for (ToRecord
(Label Symbol "value", Label Symbol "name") (Int, [Char]))
arising from a use of `toRecord'
Possible fix:
add an instance declaration for
(ToRecord
(Label Symbol "value", Label Symbol "name") (Int, [Char]))
In the expression: toRecord (value, name) (5 :: Int, "age")
In an equation for `test':
test = toRecord (value, name) (5 :: Int, "age")

此外,如果删除 test 行并将文件加载到 GHC 中。实例丢失(使用 :i ToRecord),仅显示虚拟的 ToRecod Char Integer

Utils Database.Harehouse.SQLFragment>:i ToRecord
class ToRecord a b where
type family Result a b :: *
toRecord :: a -> b -> Result a b
-- Defined at Database/Harehouse/Utils.hs:15:7
instance ToRecord Char Integer
-- Defined at Database/Harehouse/Utils.hs:27:10

有什么想法吗(我正在使用 GHC 7.6.3)?

最佳答案

错误非常明显:编译器推断该实例必须是 ToRecord (Label Symbol "value", Label Symbol "name") (Int, [Char]),但没有这样的实例存在。您隐式编写的实例还有另一个参数:参数的类型。在这种情况下,您拥有的是 ToRecord (Label (t1::*), Label (t2::*)) (v1, v2) - 除非您使用 PolyKinds ,所有多态类型都变成*。例如:

l0 = Label :: Label Int
l1 = Label :: Label Bool

test = toRecord (l0, l1) (5 :: Int, "age")

会编译得很好。如果您打开PolyKinds,您可以编写

instance ToRecord (Label (t1 :: k), Label (t2 :: k)) (v1, v2) where

然后你的例子就可以工作了:

>toRecord  (value, name) (5 :: Int, "age")
Record{value=5,name="age"}

我无法重现某些实例未显示的问题。

澄清说明:

也许我不应该说得很清楚。种类,是类型的类型,就像类型一样,是构造函数的参数。 Label 实际上有两个参数:type 参数和类型参数的kind。首先写入 kind 参数 - 因此,您有 value::Label Symbol "value" (Symbol 是字符串类型文字的 kind)。当然,你不能这样写,但GHC就是这样打印的。

种类可以像类型一样被推断。默认情况下,推断的类型将为*。在您的代码中,ToRecord (Label t1, Label t2) (v1, v2) 中的 t1t2 类型为 * 。因此,Label("value"::Symbol)Label(t1::*)无法统一。

t1::kt1::Symbol 的工作方式与 (f::Integral a => a -> a) (1::Int)(f::Int -> Int) (1::Int) 都有效。您需要 KindSignatures 扩展来编写 t1::Symbol,但 KindSignatures 是由 DataKinds 隐含的PolyKinds.

关于haskell - 实例未导出?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24714801/

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