在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就是在那里。
答案 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
实现。