gpt4 book ai didi

haskell - 由各个部分组成一个Storable

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

我想将一个Foreign.Storable分成两部分......

import Foreign

data FullData type1 type2 = FullData {first::type1, second::type2}

instance (Storable type1, Storable type2)=>Storable (FullData type1 type2) where
sizeOf _ = sizeOf (undefined::type1) + sizeOf (undefined::type2)
alignment _ = 0 --I am just setting this to zero for testing....

main = putStrLn $ show $ sizeOf (undefined::FullData Int Char)

然而这失败了 -

storableTest.hs:13:44:
Could not deduce (Storable a1) arising from a use of `sizeOf'
from the context (Storable type1, Storable type2)
bound by the instance declaration at storableTest.hs:12:10-74
The type variable `a1' is ambiguous
Possible fix: add a type signature that fixes these type variable(s)
Note: there are several potential instances:
instance (Storable type1, Storable type2) =>
Storable (FullData type1 type2)
-- Defined at storableTest.hs:12:10
instance Storable Bool -- Defined in `Foreign.Storable'
instance Storable Char -- Defined in `Foreign.Storable'
...plus 16 others
In the second argument of `(+)', namely
`sizeOf (undefined :: type2)'
In the expression:
sizeOf (undefined :: type1) + sizeOf (undefined :: type2)
In an equation for `sizeOf':
sizeOf _
= sizeOf (undefined :: type1) + sizeOf (undefined :: type2)

这里有一些更重要的事实-

  1. 即使我使用 ExistentialQuantification 或 RankNTypes 并直接在数据定义中(构造函数外部或字段本身)声明 (Storable type1, Storable type2),也会出现相同的错误。

  2. 如果我将 sizeOf 定义更改为

    ,我就可以让它工作

    sizeOf (FullData x y) = sizeOf x + sizeOf y

但这仅在我有 FullData 的具体实例时才有效,并且我的一些程序需要在创建实例之前知道数据的大小(我知道,我可以只有一个虚拟实例,但这似乎有点丑)。

最佳答案

发生此错误的原因是 :: typeN sizeOf 定义中的注释不要在实例声明中引用同名的类型。这就是 Haskell 的工作方式 - 类型变量的作用域仅在它们出现的类型签名范围内。

名为 ScopedTypeVariables 的扩展程序会改变这一点。除此之外,它使实例声明中使用的类型变量的范围覆盖声明中的所有定义。

只需在文件开头插入以下行:

{-# LANGUAGE ScopedTypeVariables #-}

或者,您实际上可以做一些比模式匹配更懒的事情。自 FullData是一条记录,访问器函数适本地限制类型。

sizeOf fd = sizeOf (first fd) + sizeOf (second fd)

只要sizeOf对于嵌套类型正确实现,即适本地非严格。由于嵌套调用 sizeOf不要评估他们的论点,对 first 的调用和second实际上不会被评估 - 但它们的类型将被计算,并强制事情正常工作。

您甚至可以使用无可辩驳的模式匹配来完成相同的操作,而不使用字段访问器:

sizeOf ~(FullData x y) = sizeOf x + sizeOf y

~向编译器断言该模式将始终匹配,并且它可以推迟实际测试它,直到 x 的值或y需要。如果您对编译器撒谎说该模式始终匹配,则当 x 时,它将生成运行时错误。或y被使用,因为它尝试查找它们但发现模式实际上没有正确匹配。这与前面的情况类似 - 如果不使用 x 和 y,一切都很好。

关于haskell - 由各个部分组成一个Storable,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20344389/

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