我有个典型:
class Monad m => Convertible m a b where
convert :: a -> m b对于许多类型,转换完全可以完成,而不需要一元效应。
现在,我知道我可以写一个相关的类型
class PureConvertible a b where
convertPurely :: a -> b然后使一个类成为另一个类的超类,并/或使用DerivingVia定义一个实例的另一个实例。
但问题是一些不一样的东西。如果我定义了一个类似类型的同义词
import Data.Kind
type PureConvertible :: Type -> Type -> Constraint
type PureConvertible a b = forall m . Monad m => Convertible m a b 这样做的想法是,如果我的转换不需要任何具体的monad特性,那么在定义m实例时也许可以避免提及Convertible。企图:
instance PureConvertible Int String where
convert _ = pure undefined唉,这不能编译。错误是:
‘convert’ is not a (visible) method of class ‘PureConvertible’奇怪的是,如果我从类型类型中删除convert方法,下面就会编译!
class Monad m => Convertible m a b where
type PureConvertible :: Type -> Type -> Constraint
type PureConvertible a b = forall m . Monad m => Convertible m a b
instance PureConvertible Int String where当类型中有方法时,是否有一种方法可以使隐藏m的类型同义词工作呢?
我用的是GHC 9.2.4一些可能有用的语言语用:
{-# LANGUAGE ConstraintKinds #-}
{-# LANGUAGE QuantifiedConstraints #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE UndecidableInstances #-}
{-# LANGUAGE StandaloneKindSignatures #-}发布于 2022-11-26 19:55:51
不是直接回答你的问题,但我建议:
import Data.Functor.Identity
type PureConvertible = Convertible Identity
convertPurely :: PureConvertible a b => a -> b
convertPurely = runIdentity . convert样板的数量是最小的,编译器应该做好优化Identity-related的工作。
https://stackoverflow.com/questions/74577425
复制相似问题