理解(,)<$>长度<*>头部的类型
我有这对函数
(,) <$> length :: Foldable t => t a -> b -> (Int, b)
(,) <$> length :: Foldable t => t a -> b -> (Int, b)
和,
head :: [a] -> a
我想了解的类型
(,) <$> length <*> head
在(<*>) :: Applicative f => f (a -> b) -> f a -> f b类型签名中,
f :: (->) [a]
a :: b
b :: (Int -> b)
因此,实例化类型将是:
(->) [a] (Int, b)
但是,我发现它的类型确实是:
(->) [a] (Int, a)
两个问题,如果可以的话:
- 为什么
b切换为a? - 这种类型签名计算的分步过程是什么?
回答
让我们继续使用签名
但改变
(<*>) :: Applicative f => f (a -> b) -> f a -> f b
到
(<*>) :: Applicative f => f (x -> y) -> f x -> f y
所以它不会让人困惑。很明显f ~ (->) [a](假设我们正在使用 foldable 的列表实例),正如您所注意到的,因此x -> y ~ b -> (Int, b)、 所以x ~ b和y ~ (Int, b)。这是您错过的部分,可能是由于命名混乱:第二个参数是f xor [a] -> b,而您传入的是head,即[a] -> a. 这会强制 b变为与 相同a,否则类型将无法解决。结果是f y, or [a] -> (Int, b),除了bnow a,给你[a] -> (Int, a)签名。