如何在递归方案中派生实例 [英] How to derive instances in recursion schemes
问题描述
我正在测试这篇文章中的一些想法。
我想为Term类型派生一个Eq实例:
{ - #LANGUAGE DeriveFunctor# - }
数据树a =分支Int [a] | Leaf Int派生(Eq,Functor,Show)
数据术语f = Term(f(Term f))派生(Eq)
但是得到这个错误:
(Eq(f(Term f)) )
由'Term'的第一个字段(类型'f(Term f)')产生
可能的修复:
使用独立的派生实例声明
,所以你可以自己指定实例上下文
当为(Eq(Term f))派生实例时
我试着添加一个独立的派生实例:
{ - #LANGUAGE DeriveFunctor# - }
{ - #LANGUAGE StandaloneDeriving # - }
数据树a =分支Int [a] | Leaf Int派生(Eq,Functor,Show)
数据Term f = Term(f(Term f))
导出实例(Eq f)=> Eq(Term f)
但是得到这个错误:
'Term'的第一个参数应该有'* - > *',
但'f'有种'*'
在'(Eq f)=>'的独立派生实例中,公式(Term f)'
现在我被卡住了。我如何显示f有一种 * - > *
?为什么我需要为 Term
但不是 Tree
的独立派生实例?两者都有类型变量,不一定会成为Eq的实例? ( a
和 f
)
有两种解决方案:
使用一些GHC扩展 StandaloneDeriving
, UndecidableInstances
和其他一些你可以写的:
派生实例(Eq(f(Term f) ))=> Eq(Term f)
这就是 recursion-schemes
在当然
-
或者,您可以使用 Eq1
来自 变形金刚
或 base-4.9.0.0
<$ p $其中
liftEq ::(a - > b - > Bool) - > f a - > f b - > Bool
eq1 ::(Eq1 f,Eq a) - > f a - > f a - > Bool
eq1 = liftEq(==)
实例Eq1 f => Eq(Term f)其中
Term a == Term b = eq1 ab
I am testing out some of the ideas in this article.
I want to derive an instance of Eq for the type Term:
{-# LANGUAGE DeriveFunctor #-}
data Tree a = Branch Int [a] | Leaf Int deriving (Eq, Functor, Show)
data Term f = Term (f (Term f)) deriving (Eq)
But get this error:
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))
I tried adding a standalone deriving instance:
{-# 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)
But get this error:
The first argument of ‘Term’ should have kind ‘* -> *’,
but ‘f’ has kind ‘*’
In the stand-alone deriving instance for ‘(Eq f) => Eq (Term f)’
Now I'm stuck. How do I show that f has a kind * -> *
? And why do I need a standalone deriving instance for Term
but not Tree
? Both have type variables that are not necessarily going to be instances of Eq? (a
and f
)
There are two solutions:
Using some GHC extensions StandaloneDeriving
, UndecidableInstances
and some others you can write:
deriving instance (Eq (f (Term f))) => Eq (Term f)
This is what recursion-schemes
does at the moment
--
Alternatively, you can use Eq1
from transformers
or base-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
这篇关于如何在递归方案中派生实例的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!