有人可以告诉我为什么吗
works : WriterT w (ReaderT r Identity) _ -> ReaderT r Identity w
works = execWriterT
但是这个
doesnt : WriterT w (Reader r) _ -> Reader r w
doesnt = execWriterT
我得到了错误
Can't find implementation for Functor (Reader r)
但是由于Reader r a
的定义是ReaderT r Identity a
,所以我们可以看到works
和doesnt
在定义上是相同的。我认为这只是实例解析算法的错误。有什么作用?
我对Idris完全陌生,我不确定是否可以以某种方式显式提供实例参数。
为了完整起见,execWriterT
的定义是:
execWriterT : Functor m => WriterT w m a -> m w
execWriterT = (map snd) . runWriterT
环境信息:
> uname -rov
4.15.0-29-generic #31-Ubuntu SMP Tue Jul 17 15:39:52 UTC 2018 GNU/Linux
> idris --version
1.3.0-git:61cf812e
编辑:同样适用于Idris版本1.3.0-git:713e485f
(截至撰写本文时为master
)
答案 0 :(得分:1)
这确实是一个库错误。 Reader
由
Reader r a = ReaderT r Identity a
通知a
是Reader
的自变量。这等于合同
Reader r = ReaderT r Identity
,但这些定义不相同。 (或者更确切地说:它们在扩展上是等效的(行为相同),但在含义上不是等效的(相同定义)。)
doesnt
不起作用的原因是,Reader r
没有减少。 Reader
用两个参数定义,Reader r
仅应用一个参数。它没有完全饱和,因此不会简化。除非您再应用一个参数,否则Idris根本不知道Reader r
与ReaderT r Identity
相关。这会导致实例解析失败,因为该实例用于ReaderT r f
,而不是Reader r
(并且您不能为Reader r
编写一个(有用的)实例,因为Reader
不是数据类型。
这有效:
Reader' : Type -> Type -> Type
Reader' r = ReaderT r Identity
doesnt : WriterT w (Reader' r) _ -> Reader' r w
doesnt = execWriterT
更正确的选择是submit a PR。