声明实例时是否可以使用类型同义词来隐藏类型变量?

dan*_*iaz 6 haskell typeclass type-synonyms

我有这个类型类:

\n
class Monad m => Convertible m a b where\n  convert :: a -> m b\n
Run Code Online (Sandbox Code Playgroud)\n

对于许多类型对,可以纯粹完成转换,而不需要一元效果。

\n

现在,我知道我可以编写一个相关的类型类,例如

\n
class PureConvertible a b where\n  convertPurely :: a -> b\n
Run Code Online (Sandbox Code Playgroud)\n

然后使一个成为另一个的超类,和/或使用 . 根据另一个定义一个的实例DerivingVia

\n

但问题是关于不同的事情。如果我定义一个类型同义词怎么办

\n
import Data.Kind\ntype PureConvertible :: Type -> Type -> Constraint\ntype PureConvertible a b = forall m . Monad m => Convertible m a b \n
Run Code Online (Sandbox Code Playgroud)\n

这个想法是,如果我的转换不需要任何具体单子的特征,我也许可以m在定义实例时避免提及。Convertible一次尝试:

\n
instance PureConvertible Int String where\n  convert _ = pure undefined\n
Run Code Online (Sandbox Code Playgroud)\n

唉,这不能编译。错误是:

\n
\xe2\x80\x98convert\xe2\x80\x99 is not a (visible) method of class \xe2\x80\x98PureConvertible\xe2\x80\x99\n
Run Code Online (Sandbox Code Playgroud)\n

奇怪的是,如果我convert从类型类中删除该方法,则会编译以下内容!

\n
class Monad m => Convertible m a b where\n\ntype PureConvertible :: Type -> Type -> Constraint\ntype PureConvertible a b = forall m . Monad m => Convertible m a b \n\ninstance PureConvertible Int String where\n
Run Code Online (Sandbox Code Playgroud)\n

m当类型类中有方法时,有没有办法使这种类型同义词隐藏工作?

\n

我正在使用 GHC 9.2.4。一些可能有用的语言指令:

\n
{-# LANGUAGE ConstraintKinds #-}\n{-# LANGUAGE QuantifiedConstraints #-}\n{-# LANGUAGE FlexibleContexts #-}\n{-# LANGUAGE FlexibleInstances #-}\n{-# LANGUAGE MultiParamTypeClasses #-}\n{-# LANGUAGE ScopedTypeVariables #-}\n{-# LANGUAGE RankNTypes #-}\n{-# LANGUAGE UndecidableInstances #-}\n{-# LANGUAGE StandaloneKindSignatures #-}\n
Run Code Online (Sandbox Code Playgroud)\n

K. *_*uhr 0

不是直接回答你的问题,但我建议:

import Data.Functor.Identity

type PureConvertible = Convertible Identity

convertPurely :: PureConvertible a b => a -> b
convertPurely = runIdentity . convert
Run Code Online (Sandbox Code Playgroud)

样板文件的数量是最少的,编译器应该很好地优化与Identity相关的废话。