为什么不(*3)`map`(+100)在伊德里斯工作?

cor*_*zza 11 haskell idris

在Haskell中,函数是仿函数,以下代码按预期工作:

(*3) `fmap` (+100) $ 1
Run Code Online (Sandbox Code Playgroud)

当然输出是303.但是,在Idris(使用fmap - > map)中,它会出现以下错误:

找不到实现 Functor (\uv => Integer -> uv)

对我来说,似乎函数在Idris中没有实现为函子,至少不像它们在Haskell中那样,但为什么呢?

此外,类型签名究竟(\uv => Integer -> uv)意味着什么?它看起来像是一些部分应用的函数,这就是函数实现所期望的,但语法有点令人困惑,特别\是应该用于lambda/literal的是在那里做什么.

小智 5

函子是一个接口。在 Idris 中,实现仅限于数据或类型构造函数,即使用data关键字定义。我不是依赖类型的专家,但我相信这个限制是必需的——至少实际上——对于一个健全的接口系统。

当您\a => Integer -> a在 REPL 中询问类型 时,您会得到

\a => Integer -> a : Type -> Type
Run Code Online (Sandbox Code Playgroud)

在 Haskell 中,我们会认为这是一个真正的类型构造函数,可以将其制成类型类的实例,例如Functor. 然而,在 Idris 中,(->)它不是类型构造函数,而是binder

与您在 Idris 中的示例最接近的是

((*3) `map` Mor (+100)) `applyMor` 1
Run Code Online (Sandbox Code Playgroud)

使用Data.Morphisms模块。或者一步一步:

import Data.Morphisms

f : Morphism Integer Integer
f = Mor (+100)

g : Morphism Integer Integer
g = (*3) `map` f

result : Integer
result = g `applyMor` 1
Run Code Online (Sandbox Code Playgroud)

这是有效的,因为它Morphism是一个真正的类型构造函数,Functor在库中定义了一个实现。