在 monad 转换器中使用类型同义词
是否可以使用类型同义词作为 monad 转换器类型构造函数的参数?特别是,如果应用的 monad 转换器有一个一元类型同义词,它是否可以用作另一个 monad 转换器中底层 monad 的类型?
据我所知,类型同义词不被接受为一流类型构造函数,请参阅下面的示例和错误消息:
-- Using type synonym of a monad transformer in another monad transformer.
import Control.Monad.Reader
-- inner transformer
type A a = ReaderT Int IO a
-- type B a = ReaderT String A a
{- Error:
readert2.hs:8:0:
Type synonym `A' should have 1 argument, but has been given 0
In the type synonym declaration for `B'
-}
-- type B a = ReaderT String (A a) a
{- Error:
readert2.hs:15:27:
Kind mis-match
The second argument of `ReaderT' should have kind `* -> *',
but `A a' has kind `*'
In the type `ReaderT String (A a) a'
In the type synonym declaration for `B'
-}
type B a = ReaderT String (ReaderT Int IO) a
{- OK -}
main = do
r <- flip runReaderT 39 $ do
n <- ask :: A Int
s <- flip runReaderT "foo" $ (ask :: B String)
return $ n + length s
print r
有没有办法避免在 B a 的定义中扩展类型同义词
A
?
Is it possible to use type synonyms as arguments of monad transformers' type constructor? In particular, if there is an unary type synonym for an applied monad transformer, could it be used as a type of the underlying monad in another monad transformer?
From what I see type synonyms are not accepted as first-class type constructors, see example and error messages below:
-- Using type synonym of a monad transformer in another monad transformer.
import Control.Monad.Reader
-- inner transformer
type A a = ReaderT Int IO a
-- type B a = ReaderT String A a
{- Error:
readert2.hs:8:0:
Type synonym `A' should have 1 argument, but has been given 0
In the type synonym declaration for `B'
-}
-- type B a = ReaderT String (A a) a
{- Error:
readert2.hs:15:27:
Kind mis-match
The second argument of `ReaderT' should have kind `* -> *',
but `A a' has kind `*'
In the type `ReaderT String (A a) a'
In the type synonym declaration for `B'
-}
type B a = ReaderT String (ReaderT Int IO) a
{- OK -}
main = do
r <- flip runReaderT 39 $ do
n <- ask :: A Int
s <- flip runReaderT "foo" $ (ask :: B String)
return $ n + length s
print r
Is there a way to avoid expanding the type synonym A
in the definition of B a
?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
类型同义词不能部分应用。在这种特定情况下,您可以编写
[或者甚至更好的
type B = ReaderT String A
以在另一个 monad 转换器中使用B
]一般而言,如果不使用 newtype 则不可能进行转换/data,例如:
不能等效地写为
type A = ...
。从某种意义上说,此功能相当于类型级别的 lambda\a ->读取一个 Int
。Type synonyms cannot be partially applied. In this specific case, you can write
[or even better
type B = ReaderT String A
to useB
in another monad transformer]It's general, that transformation is impossible without using newtype/data, for example:
cannot be equivalently written as
type A = ...
. In some sense, this feature would be equivalent to type-level lambda\a -> Reader a Int
.