Learn You a Haskell的一个例子是:
pure (+) <*> Just 3 <*> Just 5
他说:
首先,我们有
pure (+)
,即Just (+)
我假设Haskell在<*>
函数上使用类型推断来确定LHS上的pure
函数将是来自Maybe
Applicative
实例的Just 5
函数。 1}}类型类(基于我们在RHS上使用Just
的事实,Maybe
是pure
)。
但是,有没有一种情况,您希望使用<*>
方法将其转换为Applicative Functor,但您不会立即通过{{1}使用它函数,因此Haskell无法确定使用哪个pure
函数?如果是这样,您将如何明确说明pure
使用哪种功能?
或者,在某些上下文中使用pure
函数的结果之前,Haskell不会尝试确定哪个pure
函数(例如当您将其提供给{时) {1}}在某些时候起作用)
答案 0 :(得分:11)
你会给它一个类型注释。如果您将其定义为变量,则可以使用顶级类型签名:
foo :: Maybe (Integer -> Integer -> Integer)
foo = pure (+)
(这也适用于let
和where
条款。)
或者,如果您在表达式中使用它,则需要编写(pure (+) :: Maybe (Integer -> Integer -> Integer))
。
您还可以获取相关的pure
函数,而无需将其应用于参数。既然我们有:
pure :: (Applicative f) => a -> f a
...我们可以说(pure :: a -> Maybe a)
获得所需类型的pure
。但(pure :: a -> Maybe a) (+)
比pure (+) :: Maybe (Integer -> Integer -> Integer)
更令人困惑,所以后者可能更有用。
问题的最后一句是正确的,但是:您可以将pure (+)
分配给没有类型签名的变量,稍后在特定的具体类型(例如Maybe (Integer -> Integer -> Integer)
)中使用它而不必完全使用任何类型的注释。 (有一个轻微的限制:如果你将它定义为没有任何类型签名的顶级变量,那么你只能将它用作一个特定类型,而不是两个在不同的地方,因为{{ 3}} ...但你可能不需要担心。)