gpt4 book ai didi

haskell - 如何在递归方案中派生实例

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

我正在测试 this article 中的一些想法.

我想派生 Term 类型的 Eq 实例:

{-# LANGUAGE DeriveFunctor #-}
data Tree a = Branch Int [a] | Leaf Int deriving (Eq, Functor, Show)
data Term f = Term (f (Term f)) deriving (Eq)

但出现此错误:

No instance for (Eq (f (Term f)))
arising from the first field of ‘Term’ (type ‘f (Term f)’)
Possible fix:
use a standalone 'deriving instance' declaration,
so you can specify the instance context yourself
When deriving the instance for (Eq (Term f))

我尝试添加一个独立的派生实例:

{-# LANGUAGE DeriveFunctor #-}
{-# LANGUAGE StandaloneDeriving #-}
data Tree a = Branch Int [a] | Leaf Int deriving (Eq, Functor, Show)
data Term f = Term (f (Term f))
deriving instance (Eq f) => Eq (Term f)

但出现此错误:

The first argument of ‘Term’ should have kind ‘* -> *’,
but ‘f’ has kind ‘*’
In the stand-alone deriving instance for ‘(Eq f) => Eq (Term f)’

现在我被困住了。如何证明 f 有一种 * -> *?为什么我需要 Term 的独立派生实例而不是 Tree?两者都有类型变量,这些变量不一定是 Eq? 的实例。 (af)

最佳答案

有两种解决方案:

使用一些 GHC 扩展 StandaloneDerivingUndecidableInstances 以及其他一些您可以编写的扩展:

deriving instance (Eq (f (Term f))) => Eq (Term f)

这就是 recursion-schemes目前做

--

或者,您可以使用 transformers 中的 Eq1base-4.9.0.0

class Eq1 f where
liftEq :: (a -> b -> Bool) -> f a -> f b -> Bool

eq1 :: (Eq1 f, Eq a) -> f a -> f a -> Bool
eq1 = liftEq (==)

instance Eq1 f => Eq (Term f) where
Term a == Term b = eq1 a b

引用:https://github.com/ekmett/recursion-schemes/blob/ffada24f92efd5bcfe71f7f0af3b4af057f50bd0/Data/Functor/Foldable.hs#L392

关于haskell - 如何在递归方案中派生实例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38958895/

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