尽管Idris是依赖类型的,可以在类型中自由使用值,但是它仍然区分函数id
和函子Identity
。为什么我不能在id
上定义Functor实例:
Functor id where
map = id
id
的类型为id : a -> a
,为什么a
无法与Type
统一,所以map @{Functor id}
的类型为(a -> b) -> id a -> id b
,即(a -> b) -> a -> b
我知道Identity
是一个类型包装器,但是为什么我需要在类型级别使用一个单独的ID,只是为了实现类型类实例的实现。
Identity
和id
的唯一区别是无法将Identity a
评估为a
,但是它仍然是Type -> Type
函数,与{{ 1}}。
答案 0 :(得分:1)
id
是一个返回其输入值作为结果的函数。如果您需要一个函数,除了返回相同的值外对其输入什么也不做,请使用id
。
Identity
是一个简单的类型包装器,它包装类型t
以产生新的类型Identity t
,其中类型Identity t
的值是仅包含一个值的记录的原始包装类型为t
。
由于Identity
是代数数据类型,因此可以在Idris中实现接口。特别是它实现了Monad
。
有时,可以通过首先定义一个采用monadic类型作为其参数之一的monad转换器来定义构造实现Monad
的类型的类型构造函数。要为此类构造函数提供任意非monad类型作为参数,请首先使用Identity
类型构造函数包装非monad类型。
有关示例,请参见库模块Control.Monad.Writer
。