gpt4 book ai didi

haskell - 实例声明的RankNTypes?

转载 作者:行者123 更新时间:2023-12-03 22:15:12 25 4
gpt4 key购买 nike

我最近一直在玩RankNTypes,想知道是否可以使用它们
在实例声明中。

这是一个使用开放数据类型的简单示例

data (Expr a, Expr b) => Add a b = Add a b deriving(Show)                          

instance (Expr a, Expr b) => Expr (Add a b)

instance (Evaluation a, Evaluation b) => Evaluation (Add a b) where
eval (Add x y) = eval x + eval y

在这里,我必须编写类似(评估a,评估b)的约束,但是基本上我只想写类似(总a。评估a)的约束。这有可能吗?

问候,
雷乔

最佳答案

(forall a . Evaluation a)并不是很有意义:这意味着每个单一类型(包括某人将来可能会使用的任何将来的类型)都是Evaluation的实例。

同样,在这种情况下,我认为您的代码列出了所需的Evaluation实例是正确的做法;需求不超过您的实际需求。

但是在某些情况下,能够按照您描述的方式对类约束进行量化当然是件好事,而且不可能直接进行。一个示例是,您可能想从MonadPlus自动生成Monoid实例(使用包装器类型以避免OverlappingInstances问题):

newtype MonoidWrapper m a = MonoidWrapper { unMonoidWrapper :: m a }

instance Monad m => Monad (MonoidWrapper m) where ...

instance (Monad m, forall a . Monoid (m a)) => MonadPlus (MonoidWrapper m) where
mzero = MonoidWrapper mempty
mplus (MonoidWrapper a) (MonoidWrapper b) = MonoidWrapper (mappend a b)

您无法编写此代码,但是使用GADT或存在类型可以模拟它,但会遇到一些语法上的麻烦:
data MonoidDict a where
MonoidDict :: Monoid a => MonoidDict a

class AlwaysMonoid m where
alwaysMonoidDict :: MonoidDict (m a) -- note the implicit forall a here

instance Monad m => Monad (MonoidWrapper m)

instance (Monad m, AlwaysMonoid m) => MonadPlus (MonoidWrapper m) where
mzero = mymzero
where
-- needed to give name to 'a' for ScopedTypeVariables
mymzero :: forall a . MonoidWrapper m a
mymzero = case (alwaysMonoidDict :: MonoidDict (m a)) of
MonoidDict -> MonoidWrapper mempty
mplus = mymplus
where
mymplus :: forall a . MonoidWrapper m a
-> MonoidWrapper m a -> MonoidWrapper m a
mymplus (MonoidWrapper a) (MonoidWrapper b)
= case (alwaysMonoidDict :: MonoidDict (m a)) of
MonoidDict -> MonoidWrapper (mappend a b)

关于haskell - 实例声明的RankNTypes?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3957192/

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