【问题标题】:How does ghci choose names for type variables? [duplicate]ghci 如何为类型变量选择名称? [复制]
【发布时间】:2019-12-16 14:14:13
【问题描述】:

我做了这个函数:

compose []     = id
compose (x:xs) = x  . (compose xs)

当我询问类型时:

:t compose
compose :: [b -> b] -> b -> b

如果 a 按字母顺序排在第一位,为什么它会给出 compose :: [b -> b] -> b -> b 而不是 compose :: [a -> a] -> a -> a

说到这里,我再补充一个例子:

badImplementationOfCompose []     = id
badImplementationOfCompose (x:xs) =  (badImplementationOfCompose xs)

:t badImplementationOfCompose
badImplementationOfCompose :: [a1] -> a2 -> a2

它可能会给出一些提示......

【问题讨论】:

  • GHCi 尝试使用出现在您使用的函数类型中的类型变量的名称。由于推理算法相当复杂,因此很难猜测哪个名字幸存下来。在这里,b 似乎来自. 的类型,或者至少这是我的猜测。执行顺序统一显然选择了那个而不是其他名称。
  • 从这两个目标中,the older one 简洁地解释了它的要点,而the newer one 讨论了一些边缘情况。
  • @duplode 感谢一如既往的帮助

标签: list haskell types ghc type-inference


【解决方案1】:

我猜这与. 的类型有关,即

(.) :: (b -> c) -> (a -> b) -> a -> c

它只是在推断类型时从那里开始替换。

a 必须等于b 并且b 必须等于c。所以简而言之,我的猜测是,如果可能的话,它会尽量使类型变量命名与使用的子函数中的类型变量名称保持一致。

【讨论】:

    【解决方案2】:

    我的猜测:

    如果没有给出函数,GHCi 以泛型类型开头,我说的是我的第二个例子:

    badImplementationOfCompose []     = id
    badImplementationOfCompose (x:xs) =  (badImplementationOfCompose xs)
    

    它的类型是idbeeing a -> a,所以如果需要另一个类型变量,它开始加一个

    badImplementationOfCompose :: [a1] -> a2 -> a2
    

    我认为,也许@chi 是绝对正确的,名字来自函数,所以我用自己的id 做了一个案例:

    id2 :: c -> c
    id2 x = x
    
    badImplementationOfCompose []     = id2
    badImplementationOfCompose (x:xs) =  (badImplementationOfCompose xs)
    

    类型符合预期:

    :t badImplementationOfCompose
    badImplementationOfCompose :: [a] -> c -> c
    

    第一个类型变量是GHCi创建的ac -> c取自id2

    【讨论】:

      猜你喜欢
      • 2012-01-21
      • 1970-01-01
      • 2017-03-05
      • 2016-01-20
      • 1970-01-01
      • 2013-06-06
      • 1970-01-01
      • 2014-11-15
      • 2018-07-21
      相关资源
      最近更新 更多