明确确定使用

问题描述:

其中一个例子来自Learn You a Haskell其中纯函数是:明确确定使用

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

他指出:

所以刚开始,我们有pure (+),这是Just (+)

我是假定Haskell在<*>函数上使用类型推断来确定LHS上的pure函数将是Applicative类型类的Maybe实例中的函数(基于我们在RHS上使用Just 5的事实,并且Just是一个Maybe)。

然而,有没有这种情况下,你有一个值,你想使用pure方法变成一个Applicative Functor,但你不会立即通过<*>函数使用它,因此Haskell可以不确定使用哪个pure函数?如果是这样,您将如何明确哪些pure功能使用

或者,难道是哈斯克尔不会试图确定哪些pure功能,直到pure函数的结果在某些情况下使用(例如,当你在某个时候将其提供给一个<*>功能)

的情况下
+1

这是一个类型推断问题。 – dave4420

你会给它一个类型注释。如果你将其定义为一个变量,你可以使用一个*类型签名:(这也适用于letwhere条款)

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

或者,如果你在表达式中使用它,你会写(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

问题文本的最后一段也是如此:通常,如果您无法决定是否使用具体的应用函子,您也不必这样做。没有必要立即选择一个具体的类型,你可以定义在应用函数中超载的派生代码。 – kosmikus