gpt4 book ai didi

haskell - 避免在 Hughes 的列表仿函数实例中使用 unsafeCoerce

转载 作者:行者123 更新时间:2023-12-04 23:44:48 24 4
gpt4 key购买 nike

我有一个新类型来表示休斯的列表(即列表构造):

newtype Hughes a = Hughes {unHughes :: [a] -> [a]}

有一些功能可以处理它:
mkHughes :: [a] -> Hughes a
mkHughes = Hughes . (++)

runHughes :: Hughes a -> [a]
runHughes h = unHughes h []
Monoid实例就像上面的函数一样简单:
instance Monoid (Hughes a) where
mempty = Hughes id
mappend (Hughes f) (Hughes g) = Hughes (f . g)

...但是当我到达 Functor 时出现了问题和 Applicative实例。这是我到目前为止想出的:
instance Functor Hughes where
fmap f (Hughes h) = Hughes $ unsafeCoerce $ fmap f . h

instance Applicative Hughes where
pure = Hughes . (:)
(<*>) (Hughes f) (Hughes v) = Hughes $ unsafeCoerce $
(<*>) <$> f <*> unsafeCoerce v

我的问题是我不喜欢使用 unsafeCoerce .有没有办法设计 Functor实例而不使用它,还是不可避免?

此外,我将如何实现 Monad此数据类型的实例?

编辑:与 DList 不同包,我想保持性能改进,即不评估 [a] -> [a]但映射它。

最佳答案

没有办法实现 Functor Hughes实例。

让我们检查 Hughes 的定义:

data Hughes a = Hughes ([a] -> [a])
^

我们可以看到参数 a在标记的位置出现逆变。一个 Functor仅当最后一个类型参数的所有外观都是协变时,实例才能存在。

基本上你被要求定义一个函数 fmap :: (a -> b) -> ([a] -> [a]) -> [b] -> [b] .问题是你不能用 [b] 做任何事情, 没有接受 [b] 的函数或 b .你可以忽略它,但是仿函数定律 fmap id = id不会举行。

至于DList, Functor instance 是有效的,因为实现不导出实际的数据构造函数,只导出智能构造函数。因此,您不能构造作为任意列表处理函数的 dlist 值。使用提供的智能构造函数,您只能构造与 [a] 同构的 dlists。 ,这就是仿函数定律成立的原因。

如果您以某种方式将构造函数 hack(带入)到作用域中,您会发现仿函数定律实际上并不适用于任意函数,例如 fmap id x /= x如果 x类似于 DList (map negate) .

关于haskell - 避免在 Hughes 的列表仿函数实例中使用 unsafeCoerce,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31362222/

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