haskell - 一个环境如何恰好是一个部分应用函数,甚至是一个 hom 仿函数?

标签 haskell category-theory

我已经多次看到 Reader 在野外被使用并带来重大好处。 (一个值得注意的例子是 stackbuilt aroundReader 的直接衍生品,可以在类型级别告知用户其内容的充足性。) 经过一番思考,我了解到这种好处仅仅是代码结构层面上的,从某种意义上说,Reader 在很多地方所做的只是提供一个参数,到复杂的功能接线。也就是说,我开始相信我们总是可以用 λx 形式的 lambda 抽象来替换持有某些 x 的读取器。 ... x ... x ... 。这似乎与 official explanations 一致该主张:

... the partially applied function type (->) r is a simple reader monad ...

但是,从注意到 Reader 是一种分段编写 lambda 抽象的方法,到声称它是一个部分应用函数,还有很长的路要走。

  1. 是否存在已应用但未部分应用的函数?它只是一个值:

    λ :t id 1
    id 1 :: Num a => a
    λ :t 1
    1 :: Num a => a
    
  2. 有没有一个函数甚至没有被部分应用?我们永远不会知道:

    λ :t fromMaybe
    fromMaybe :: a -> Maybe a -> a
    λ :t flip maybe id
    flip maybe id :: b -> Maybe b -> b
    

即使忽略这一点,我也不会相信 (->) r (为什么不直接写 (r ->)?) 完全是一个Reader monad。也许我可以编写一个类型检查的实例。也许它甚至会遵守法律。只要我不认为我的功能是Reader,只要我没有正确的直觉,它的愿景,它对我来说就同样有用作为四色定理的第一个证明。另一方面,我如何确定这是在函数上定义 monad 的唯一方法? Num 上有多个 MonoidList 上至少有两个 Applicative - 这不是太鲁莽地将函数视为单独的 Reader monad?

困境并没有结束。当我去寻找答案时,我偶然发现了一个even more puzzling注意:Reader 现在恰好是 hom 仿函数,甚至是一般可表示的仿函数。而来自另一端的人们实际上提前知道 Haskell 中会有这样的构造,甚至拼写它的类型,与上述官方解释中的拼写相同。现在,这超出了我的理解范围,但我可以从 Mac Lane 解析 hom 仿函数的定义。通过一些想象,可以看出,如果将函数 a -> b 作为(假定的)类别 Hask 中的态射,我们可以将其与 组合id 再次获取...函数 a -> b,这次作为集合 hom(a, b) 的元素。

这与部分应用的某些态射有什么联系吗?或者使用 Reader 作为 stack 中的选项存储?我真的可以看到 hom 仿函数 Hask -> Set 的对象和箭头函数吗? (我将采用一个endofunctor Hask -> Hask作为合理的近似值。)那是我值得信赖的伙伴pure吗? > 和fmap

那么,之后我该如何实际使用 Reader 呢?

最佳答案

我无法回答您的所有问题,但让我们从简单的问题开始:

(->) r (why not just write (r ->)?)

因为后者是Haskell中的语法错误。您不能在类型上使用此部分语法。


... claiming that it is a partially applied function.

事情不是这么说的。引用如下:

the partially applied function type (->) r is a simple reader monad

这是一个部分应用的类型,而不是一个部分应用的函数。或者换句话说,它是这样解析的:((部分应用)(函数类型))

Haskell 中函数类型的类型构造函数拼写为 -> .

完全应用的函数类型类似于 r -> a (或等效 (->) r a ),其中 r是参数类型且 a结果类型。

因此(->) r-> 的部分应用(函数类型)。


如果我们忽略 monad 转换器和 ReaderTReader 的简单定义是:

newtype Reader r a = Reader (r -> a)

runReader :: Reader r a -> r -> a
runReader (Reader f) x = f x
-- or rather:
runReader :: Reader r a -> (r -> a)
runReader (Reader f) = f

或等效的:

newtype Reader r a = Reader{ runReader :: r -> a }

Reader只是 -> 的新类型(非常薄的 wrapper ),带有 runReader用于展开。

您甚至可以制作-> MonadReader 的一个实例只需复制 Reader 的实例即可并删除所有 Reader/runReader包装/展开。

关于haskell - 一个环境如何恰好是一个部分应用函数,甚至是一个 hom 仿函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49088510/

相关文章:

haskell - 为什么我不能使用类型 `Show a => [Something -> a]` ?

haskell - 自动管理导入或重构模块的脚本

Haskell:Control.Category.Monoidal:关联、idl 和 idr 的逆

haskell - 不理解 Monoid 定义中态射的表示法

opengl - 如何使用 GLUT 和 OpenGL 安装 Haskell?

haskell - GHCi 中 Applicative 的 pure 的奇怪行为

haskell - 事务类型安全

haskell - 笛卡尔类的这些类扩展是做什么用的?

haskell - monad bind (>>=) 运算符是否更接近函数组合(链接)或函数应用程序?

haskell - Haskell 中 Zap Functor 和 zap 函数的目的是什么?