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

时间:2018-05-09 18:05:41

标签: haskell idris

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

SELECT entity_id, attribute_name, COUNT(attribute_name) AS NumOcc 
FROM (SELECT DISTINCT * FROM radiology) x 
GROUP BY entity_id,attribute_name 
HAVING COUNT(attribute_name) > 1

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

  

无法找到(*3) `fmap` (+100) $ 1

的实施方式

对我来说,似乎函数在Idris中没有像functor一样实现,至少不像Haskell那样,但为什么会这样?

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

1 个答案:

答案 0 :(得分:4)

Functor是一个界面。在Idris中,实现仅限于数据或类型构造函数,即使用data关键字定义。我不是依赖类型的专家,但我认为这种限制是必需的 - 实际上,至少对于一个完善的接口系统。

当你在REPL上询问\a => Integer -> a的类型时,你会得到

\a => Integer -> a : Type -> Type

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

与你在伊德里斯的例子最接近的是

((*3) `map` Mor (+100)) `applyMor` 1

使用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

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