Idris中的实例解析

时间:2018-08-04 13:12:57

标签: idris

有人可以告诉我为什么吗

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,所以我们可以看到worksdoesnt在定义上是相同的。我认为这只是实例解析算法的错误。有什么作用?

我对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

1 个答案:

答案 0 :(得分:1)

这确实是一个库错误。 Reader

定义
Reader r a = ReaderT r Identity a

通知aReader的自变量。这等于合同

Reader r = ReaderT r Identity

,但这些定义不相同。 (或者更确切地说:它们在扩展上是等效的(行为相同),但在含义上不是等效的(相同定义)。)

doesnt不起作用的原因是,Reader r没有减少。 Reader用两个参数定义,Reader r仅应用一个参数。它没有完全饱和,因此不会简化。除非您再应用一个参数,否则Idris根本不知道Reader rReaderT 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