最常见的"产品" Haskell中的两个函数

时间:2015-07-11 22:53:34

标签: haskell types type-inference unification

我必须从Haskell中的给定函数中找到最常规的类型,或者更确切地说找到"产品的最一般类型"两个函数,如果它存在。我不确定但也许我应该使用Robinson统一算法,但我无法理解它。我需要一步一步的详细解决方案,所以我能理解。

功能:

map :: (a → b) → [a] → [b] 
iterate :: (a → a) → a → [a]

如何找到

的最常规类型
  1. map iterate
  2. iterate map
  3. 这不是作业。

2 个答案:

答案 0 :(得分:5)

让我们问GHCi:

ghci> :type map . iterate
map . iterate :: (a -> a) -> [a] -> [[a]]
ghci> :type iterate . map
iterate . map :: (a -> a) -> [a] -> [[a]]

让我们看看它是如何得到的:

鉴于

map     :: (x -> y) -> [x] -> [y]
iterate :: (b -> b) -> b -> [b]
(.)     :: (s -> t) -> (r -> s) -> (r -> t)

使用a ~ b表示“类型ab相等”。

然后在map . iterate我们有

map :: s -> t where
 s ~ x -> y
 t ~ [x] -> [y]

iterate :: r -> s where
 r ~ b -> b
 s ~ b -> [b]

so
 x -> y ~ s ~ b -> [b]
=>
 x ~ b
 y ~ [b]
 t ~ [b] -> [[b]]

所以map . iterate :: (b -> b) -> [b] -> [[b]]

然后在iterate . map我们有

iterate :: r -> s where
 s ~ b -> b
 t ~ b -> [b]

map :: s -> t where
 r ~ x -> y
 s ~ [x] -> [y]

so
 b -> b ~ s ~ [x] -> [y]
 b ~ [x]
 b ~ [y]
 x ~ y
 r ~ x -> x
 t ~ [x] -> [[x]]

所以iterate . map :: (x -> x) -> [x] -> [[x]]

虽然这些功能具有相同的类型,但它们的行为却截然不同。

  • iterate . map将给定一个函数和一个长度为k的列表,生成一个长度为k的列表的无限列表。
  • map . iterate将给定一个函数和一个长度为k的列表,生成一个长度为k无限列表的列表。

答案 1 :(得分:4)

首先,明确写出所有省略的括号。

要派生类型a -> b的函数的应用类型和类型c的值,我们需要统一类型ac,注意任何结果类型等价。然后,在所述等价下,应用程序的类型为b。规则是:

f   ::     a → b
x   ::     c
        ----------
f x ::         b      , { a ~ c }

要找到半机械的,只需对齐类型并注意等价:

map ::    (   a1     →     b1     ) → ([a1] → [b1]) 
iterate :: (a2 → a2) → (a2 → [a2])
          --------------------------
        { a1 ~ (a2 → a2) , b1 ~ (a2 → [a2]) }

所以,

map iterate :: [a1] → [b1]

从等价代替,我们得到

            :: [a2 → a2] -> [a2 → [a2]]

现在我们可以将a2重命名为a,或t,或其他任何内容。你的第二个例子是类似的:

iterate :: (   a2     →       a2     ) → (a2 → [a2])
map ::      (a1 → b1) → ([a1] → [b1]) 
           ---------------------------
        { a2 ~ a1 → b1 ,  a2 ~ [a1] → [b1] }

a2 ~ a2以来,我们得到a1 → b1 ~ [a1] → [b1]

               a1  →  b1
              [a1] → [b1]
            --------------
        { a1 ~ [a1] ,  b1 ~ [b1] }

两种等价都是不可能的,定义无限类型。所以第二个例子在Haskell中没有类型:

  

*主> :t map iterate
  map iterate :: [a - > a] - > [a - > [a]]
   
  *主> :t迭代地图
    
  :1:9:
      发生检查:无法构造无限类型:a~ [a]
      预期类型:(a - > b) - > a - > b
        实际类型:(a - > b) - > [a] - > [b]
      在'iterate'的第一个参数中,即'map'       在表达式中:迭代映射
    
  :1:9:
      发生检查:无法构造无限类型:b~ [b]
      预期类型:(a - > b) - > a - > b
        实际类型:(a - > b) - > [a] - > [b]
      在'iterate'的第一个参数中,即'map'       在表达式中:迭代地图