gpt4 book ai didi

frege - Functor 实例是否可以声明为函数的附加类型限制

转载 作者:行者123 更新时间:2023-12-01 07:13:57 27 4
gpt4 key购买 nike

我正在努力将 GHC/Arr.hs 移植到弗雷格。

数组定义:

data Array i e = Array{u,l::i,n::Int,elems::(JArray e)}

有函数:

amap :: (Ix i, ArrayElem e) => (a -> b) -> Array i a -> Array i b

现在,我不知道如何为它定义 Functor 实例,因为

instance (Ix i) => Functor (Array i) where
fmap = amap

但是编译器提示推断的类型比预期的更受限制,这似乎是真的。我可以使 Array 成为对函数 ArrayElem -> ArrayElem 有限制的仿函数吗?

最佳答案

不,这是不可能的。

如果您将 Array 基于 JArray 并且想要一个仿函数实例,则不得使用任何出现 ArrayElem(或任何其他附加)上下文的函数。

另一种说法是,您不能将 Array 基于类型安全的 java 数组,而必须处理类型为 Object[] 的 java 数组。因为,正如您毫无疑问指出的那样,ArrayElem 类型类只是一个技巧,可以在创建 java 数组时提供正确的 java 类型。当然,这对于与 Java 交互和出于性能原因很重要。

请注意,类型安全的 java 数组还有另一个问题。假设我们想要制作一个 Double 的数组(但相同的参数适用于任何其他元素类型)。 AFAIK,Haskell 要求 Arrays 元素必须是惰性的。因此,我们真的不能使用 java 类型 double[](JArray Double 将是 Frege 对应物)对其进行建模。因为,如果我们这样做,每个数组元素都必须在设置后立即求值。

出于这个原因,我建议您使用一些通用的自定义数组元素类型,例如

data AElem a = AE () a 
mkAE = A ()
unAE (AE _ x) = x
derive ArrayElement AElem

并改变你的定义:

data Array i e = Array{u,l::i,n::Int,elems::(JArray (AElem e))}

现在,你的仿函数实例可以写了,因为 ArrayElem 约束没有出现,因为当你访问 elems 数组时,编译器知道你有 AElem 元素并且能够并且将会提供正确的实例。

此外,AElem 的构造和 AElem 作为实际数组元素的使用不会对实际值施加严格性。

不用说,Array 模块的用户不应该(不需要)知道那些实现细节,即 AElem 类型。

关于frege - Functor 实例是否可以声明为函数的附加类型限制,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33223451/

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