haskell - Haskell:理解 Applicative 函子的纯函数
问题描述
我正在学习 Applicative Functors 并且纯函数具有以下类型声明:
pure :: a -> f a
我知道纯函数接受任何类型的值并返回一个应用值,其中包含该值。所以如果应用实例是Maybe
,pure 3
就会给出Just 3
。
但是,当您将 pure 应用于已经在应用值内的值时会发生什么?例如,如果你做类似的事情会发生什么pure Just 3
?
解决方案
当您将 pure 应用于已经在应用值内的值时会发生什么?
它只是被包裹在一个额外的层中。最终结果是嵌套在另一个应用值中的应用值。
例如,如果你做类似的事情会发生什么
pure Just 3
?
这是一个有趣的问题,尽管可能不是出于您的意思。这里的重点是区分pure (Just 3)
——这可能是你的意思——和pure Just 3 = (pure Just) 3
你写的。这给出了两种情况:
pure (Just 3)
简单地应用于pure
valueJust 3
,正如我上面讨论的那样,它给出了Just (Just 3)
,这是一个嵌套的应用值。(pure Just) 3
是一个有趣的案例。回想 和 的pure
类型Just
:pure :: Applicative f => a -> f a Just :: a -> Maybe a -- so: pure Just :: Applicative f => f (a -> Maybe a)
换句话说,
pure Just
获取函数Just
并将其包装在一个应用值中。接下来,我们要将其
pure Just
应用于 value3
。但我们不能这样做,因为f (a -> Maybe a)
它是一个值,而不是一个函数!所以(pure Just) 3
应该导致类型错误。......但事实证明类型检查很好!所以我们错过了一些东西。在这种情况下,事实证明有一个函数的应用实例:
instance Applicative ((->) r) where pure x = \r -> x (<*>) = _irrelevant_here
语法有点滑稽,但它基本上意味着这
r -> ...
是一个应用程序。这个特定的实例被称为Reader monad,它的使用非常广泛。(有关此特定数据类型的更多信息,请参见此处或此处。)这个想法是r -> a
可以计算a
给定的r
输入;在这种情况下,pure x
创建一个忽略其输入并x
始终返回的函数,并将f <*> x
输入r
输入到两者f
中x
,然后将两者结合起来。在这种情况下,我们只使用pure
,因此很容易(pure Just) 3
手动评估:(pure Just) 3 = (\r -> Just) 3 = Just
所以这里的想法是
pure
包装Just
一个应用值,在这种情况下它恰好是一个函数;然后,我们将此函数应用于3
,它摆脱了包装器以显示原始Just
。
推荐阅读
- python - 将列表中的字符串元素转换为单独的变量
- modelica - 缺少起始值
- verilog - Verilog垃圾输入不会导致垃圾输出
- sql - 选择空字符串作为列时,SQL UNION 考虑了字符数
- c# - 在 C# 中获取 WPF TabControl 的当前选定选项卡的 ListView
- c++ - 有没有办法在while循环中存储变量?
- python - 在使用 python/pandas 循环时写入一个独特的 Excel 表
- python - Python 3.x 运行问题,ALL IDEA 无法读取 Python 3.x 的库
- r - 如何在ggplot上画一个grob?
- django - Django 没有为第三方应用程序获取覆盖的翻译