【问题标题】:Why does the partial application `foldr id` typecheck?为什么部分应用程序`foldr id`类型检查?
【发布时间】:2016-04-08 16:16:19
【问题描述】:

在 Haskell 中,我不明白为什么部分应用程序 foldr id 会进行类型检查。

相关类型是

> :t foldr id
foldr id :: a -> [a -> a] -> a

> :t foldr
foldr :: (a -> b -> b) -> b -> [a] -> b

> :t id
id :: a -> a

foldr 的第一个参数是(a->b->b)。相反,id 的类型是a->a。它们不应该兼容。

【问题讨论】:

  • :t id :: (a -> a) -> (a -> a) 可能很有启发性。
  • @ChadGilbert 感谢您的编辑。仅供参考,您可以只写一次<!-- language-all: haskell -->

标签: haskell types type-inference fold partial-application


【解决方案1】:

因为a -> b -> b 实际上是a -> (b -> b)

由于id :: a -> a,这将ab -> b 统一起来,因此我们得到,类型变量一致地重命名以实现唯一性,

foldr :: (a -> (b -> b)) -> b -> [  a   ] -> b
id    ::  c ->    c
-----------------------------------------------   |-  a ~ c ,  c ~ b -> b
foldr       id           :: b -> [  c   ] -> b
foldr       id           :: b -> [b -> b] -> b

就是这样。

那么它有什么作用呢?

foldr f z [x, y, ..., n]  =  f x (f y (... (f n z)...))
                          =  x `f` y `f` ...  n `f` z     -- infixr _ `f`

foldr id z [x, y,  ...,    n] =
    = id x (id y ( ... (id n        z )...))
    =    x (   y ( ... (   n ( id   z))...))
    = (  x .   y .  ...  . n . id ) z
    = foldr  (.)  id  [x,y,...,n]   z

因此foldr id = foldr ($) = flip (foldr (.) id) 非常好。列表中的函数全部堆叠起来,因为输出和输入类型匹配。

【讨论】:

    猜你喜欢
    • 2022-11-21
    • 2011-05-09
    • 1970-01-01
    • 1970-01-01
    • 2014-12-04
    • 1970-01-01
    • 2019-06-19
    • 2018-12-29
    • 1970-01-01
    相关资源
    最近更新 更多