gpt4 book ai didi

haskell - 具有更高种类类型的类型类约束

转载 作者:行者123 更新时间:2023-12-01 09:16:21 24 4
gpt4 key购买 nike

我正在尝试写一个 Eq EitherT 的实例newtype 给出:

newtype EitherT e m a = EitherT { runEitherT :: m (Either e a) }

我假设以下 Eq实例将工作:
instance (Eq e, Eq a, Eq m) => Eq (EitherT e m a) where
a == b = (runEitherT a) == (runEitherT b)

但是,我看到一个错误:
Expected kind '* -> *', but 'm' has kind '*'

我从那个错误中读到的是我的类型类约束 ( ... Eq m) => ...使编译器误以为我相信 m善待 * , 当我对 EitherT 的 newtype 声明时希望它是善良的 * -> * .

我想知道我需要做什么,声明我想要一个 Eq例如一些更高级的类型 m实现 Eq我的 EitherT新型。

编辑:正如@AlexisKing 所指出的,我可以使用它:
{-# LANGUAGE UndecideableInstances #-}
instance (Eq (m (Either e a))) => Eq (EitherT e m a) where
a == b = (runEitherT a) == (runEitherT b)

然而,我觉得奇怪的是,写这个 Eq 需要语言扩展。实例。有没有其他方法可以在 vanilla Haskell 中表达这样的类型类约束?如果不是,为什么?

最佳答案

您正在寻找 Eq1这是在 Data.Functor.Classes 从基础 4.9.0.0 开始。在此之前,它位于 -extras 之一包裹或 transformers ? (它是 in transformers now since 0.4.0.0 )
Eq1 f说你可以比较f只要你有办法比较它们的内容

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

在你的情况下,你会像这样使用它
instance (Eq e, Eq1 m) => Eq1 (EitherT e m) where
liftEq f a b = liftEq (liftEq f) (runEitherT a) (runEitherT b)
liftEq f是使用现有的 Eq1 Either 的实例.

并且可以定义一个 Eq实例为
instance (Eq e, Eq a, Eq1 m) => Eq (EitherT e m a) where
(==) = liftEq (==)

Eq1曾是
class Eq1 f where
eq1 :: (Eq a) => f a -> f a -> Bool

在你的情况下,你会像这样使用它
instance (Eq e, Eq1 m) => Eq1 (EitherT e m) where
eq1 a b = eq1 (runEitherT a) (runEitherT b)

instance (Eq e, Eq a, Eq1 m) => Eq1 (EitherT e m) where
a == b = eq1 (runEitherT a) (runEitherT b)

关于haskell - 具有更高种类类型的类型类约束,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43699207/

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