【发布时间】:2015-07-15 04:51:05
【问题描述】:
我正在尝试学习 Haskell,在使用应用函子时,我发现一件事让我很困惑。
让我们定义以下函数g,它返回一些函子:
*Main> let g = pure (2*)
*Main> :t g
g :: (Num a, Applicative f) => f (a -> a)
由于返回类型是 some 函子,我可以在这两个函数中使用 g 作为参数:
f1 :: (Num a) => [a -> a] -> a
f1 (g:[]) = g 3
f2 :: (Num a) => Maybe (a -> a) -> a
f2 (Just g) = g 4
但这意味着函数 g 返回的值也取决于将被评估的上下文! (可能是 List 和 Maybe。)这也是懒惰的属性吗?因为到目前为止,我一直在以一种在需要时计算值的方式来考虑惰性,但它在定义时已经确定(对于 g in let 表达式)。
【问题讨论】:
-
这与懒惰无关。这只是常规的重载。
-
@augustss 好的,现在我知道在 Haskell 中也可以重载单个值(因此我的示例过于复杂;)。但我仍然认为这在某种程度上取决于懒惰。如果在需要它的值时不评估该值,就不可能重载它,对吧?
-
@MartinJiřička 具有多态类型的值实际上并不是惰性行为——它们的行为类似于函数。也就是说,您每次使用它们时都会对它们进行评估,而不仅仅是第一次使用它们。所以它不起作用是因为懒惰(它不适用于懒惰),而是因为与单态值相比,多态值得到特殊处理。
-
我对自己的回应是:不,这与懒惰无关,因为它与何时计算值无关,而是选择了哪个值(根据预期的类型)。但现在我发现我的原始示例中的函数与本例略有不同。
-
另外,这个想法是
g确实是某种闭包(当我将它变成一个从Applicative f到f (a -> a)的函数时,它是明确的),因此,它是已经一个值。微妙之处在于,它的参数是由编译器而不是用户在其使用站点选择的。
标签: haskell applicative