理解(,)<$>长度<*>头部的类型

F. *_*Zer 3 haskell types type-inference applicative type-signature

我有这对函数

(,) <$> length :: Foldable t => t a -> b -> (Int, b)
Run Code Online (Sandbox Code Playgroud)

和,

head :: [a] -> a
Run Code Online (Sandbox Code Playgroud)

我想了解的类型

(,) <$> length <*> head
Run Code Online (Sandbox Code Playgroud)

(<*>) :: Applicative f => f (a -> b) -> f a -> f b类型签名中,

f :: (->) [a]

a :: b

b :: (Int -> b)

因此,实例化类型将是:

(->) [a] (Int, b)
Run Code Online (Sandbox Code Playgroud)

但是,我发现它的类型确实是:

(->) [a] (Int, a)
Run Code Online (Sandbox Code Playgroud)

两个问题,如果可以的话:

  • 为什么b切换为a
  • 这种类型签名计算的分步过程是什么?

Apl*_*123 5

让我们继续使用签名

(,) <$> length :: Foldable t => t a -> b -> (Int, b)
Run Code Online (Sandbox Code Playgroud)

但改变

(<*>) :: Applicative f => f (a -> b) -> f a -> f b
Run Code Online (Sandbox Code Playgroud)

(<*>) :: Applicative f => f (x -> y) -> f x -> f y
Run Code Online (Sandbox Code Playgroud)

所以它不会让人困惑。很明显f ~ (->) [a](假设我们正在使用 foldable 的列表实例),正如您所注意到的,因此x -> y ~ b -> (Int, b)、 所以x ~ by ~ (Int, b)。这是您错过的部分,可能是由于命名混乱:第二个参数是f xor [a] -> b,而您传入​​的是head,即[a] -> a. 这会强制 b变为与 相同a,否则类型将无法解决。结果是f y, or [a] -> (Int, b),除了bnow a,给你[a] -> (Int, a)签名。