我正在测试this article中的一些想法。
我想为Term:
类型派生一个Eq实例$("#datepicker").blur(function(){
var date = $(this).datepicker('getDate')
val = $(this).val();
year = date.getFullYear();
val1 = Date.parse(val);
if (year < 2016){
alert("error")
}
else{
console.log(val1);
}
});
});
但是得到这个错误:
{-# 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)
现在我被卡住了。如何显示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)’
种类?为什么我需要* -> *
而不是Term
的独立派生实例?两者都有类型变量,不一定是Eq的实例? (Tree
和a
)
答案 0 :(得分:8)
有两种解决方案:
使用一些GHC扩展StandaloneDeriving
,UndecidableInstances
和其他一些你可以写的:
deriving instance (Eq (f (Term f))) => Eq (Term f)
这是recursion-schemes
目前所做的事情
-
或者,您可以使用transformers
或Eq1
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