【问题标题】:Deriving the type of ((.) foldr)导出 ((.) foldr) 的类型
【发布时间】:2014-05-01 19:34:29
【问题描述】:

我正在尝试手动导出 ((.) foldr) 的类型

(.) ::(b1 -> c1) -> (a1 -> b1) -> a1 -> c1
foldr :: (a2 -> b2 -> b2) -> b2 -> [a2] -> b2

然后:

b1 = a2 -> b2 -> b2
c1 = b2 -> [a2] -> b2

匹配我得到的类型:

((a2 -> b2 -> b2) -> (b2 -> [a2] -> b2)) -> (a1 -> (a2 -> b2 -> b2)) -> a1 -> (b2 -> [a2] -> b2)

但后来我对如何减少这种表达感到困惑。

有什么帮助吗?

谢谢,
塞巴斯蒂安。

【问题讨论】:

  • 这个问题的题目问的是(foldr (.)),但在实际问题中你使用((.) foldr)。请编辑以使他们同意。

标签: haskell types unification


【解决方案1】:

您正确计算出(.) foldr(.) 的类型。 (.) 应用于一个参数(foldr),因此您可以丢弃((a2 -> b2 -> b2) -> (b2 -> [a2] -> b2)),剩下的就是(.) foldr 的类型:

(a1 -> a2 -> b2 -> b2) -> a1 -> (b2 -> [a2] -> b2)

确保foldr 可以具有((a2 -> b2 -> b2) -> (b2 -> [a2] -> b2)) 类型,然后再将其丢弃。如果匹配正确,则此检查不会失败,但它是一个很好的健全性检查。

【讨论】:

    【解决方案2】:

    如果我们有

    (.)   :: (b -> c) -> (a -> b) -> (a -> c)
    foldr :: (x -> y -> y) -> y -> [x] -> y
    

    那么对于(.) foldrb -> c 必须与foldr 的类型对齐,所以

    b             -> c
    (x -> y -> y) -> (y -> [x] -> y)
    

    这意味着

    b ~ (x -> y -> y)
    c ~ (y -> [x] -> y)
    

    所以代入:

    --                 b                       c
    (.) foldr :: (a -> (x -> y -> y)) -> (a -> (y -> [x] -> y))
    

    由于-> 是左关联的,我们可以去掉多余的括号:

    (.) foldr :: (a -> x -> y -> y) -> (a -> y -> [x] -> y)
    

    如果你愿意,你可以更进一步

    (.) foldr :: (a -> x -> y -> y) -> a -> y -> [x] -> y
    

    所以如果我们问 GHCi 是什么类型,我们会得到

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

    a ~ aa1 ~ xb ~ y,所以我们得到了正确答案。

    【讨论】:

      猜你喜欢
      • 2014-06-18
      • 1970-01-01
      • 2019-01-02
      • 1970-01-01
      • 2015-05-21
      • 1970-01-01
      • 1970-01-01
      • 2019-08-31
      • 1970-01-01
      相关资源
      最近更新 更多