5

Learn You a Haskell中的一个例子是:

pure (+) <*> Just 3 <*> Just 5

他说:

所以一开始,我们有pure (+),即Just (+)

我假设 Haskell 正在函数上使用类型推断<*>来确定pureLHS 上的函数将来自类型类的Maybe实例Applicative(基于我们在Just 5RHS 上使用的事实,并且Just是 a Maybe)。

但是,是否有过这样的情况,您想使用该pure方法将一个值转换为 Applicative Functor,但您不会立即通过该<*>函数使用它,因此 Haskell 无法确定要使用哪个pure函数利用?如果是这样,您将如何明确说明pure要使用哪个功能

或者,是不是 Haskell 不会尝试确定哪个pure函数,直到函数的结果pure在某些上下文中使用(例如当你<*>在某个时候将它提供给函数时)

4

1 回答 1

11

你会给它一个类型注释。如果您将其定义为变量,您将使用顶级类型签名:

foo :: Maybe (Integer -> Integer -> Integer)
foo = pure (+)

(这也适用于letandwhere子句。)

或者如果你在表达式中使用它,你会写(pure (+) :: Maybe (Integer -> Integer -> Integer)).

您还可以获取相关pure函数,而无需将其应用于参数。因为我们有:

pure :: (Applicative f) => a -> f a

...我们可以说(pure :: a -> Maybe a)得到pure所需类型的 a。But(pure :: a -> Maybe a) (+)比 更令人困惑pure (+) :: Maybe (Integer -> Integer -> Integer),因此后者通常可能更有用。

但是,您问题的最后一句话是正确的:您可以分配pure (+)给没有类型签名的变量,然后在特定的具体类型(例如Maybe (Integer -> Integer -> Integer))中使用它,而根本不必使用任何类型注释。(有一个轻微的限制:如果你将它定义为没有任何类型签名的顶级变量,那么你只能将它用作一个特定类型,而不是两个在不同的地方,由于单态限制......但你可能不不必担心这一点。)

于 2012-07-04T16:48:50.620 回答