如何告诉类型检查器绑定中的类型签名是否匹配顶级类型签名?

时间:2017-03-11 21:39:37

标签: haskell typechecking parametric-polymorphism

背景

我喜欢在我的wherelet绑定中添加类型签名,因为它有助于我记住我需要的结果和输入内容。它还有助于类型检查器在我弄错时给我一个明确的错误消息。但是,它最近给我带来了问题:

鉴于

这是一个公认的最低限度的例子:

data Foo a = Foo a | NotFoo                  -- 3 
                                             -- 4 
data Bar a = Bar a                           -- 5 
                                             -- 6 
funct :: Bar a -> (a -> Foo a) -> Bar a      -- 7 
funct (Bar x) fn = loop (Bar x, Foo x)       -- 8 
  where                                      -- 9 
    loop :: (Bar a,Foo a) -> Bar a           -- 10
    loop (x, (Foo y)) = loop (Bar y, fn y)   -- 11
    loop (x, NotFoo) = x                     -- 12

GHC吐出错误:

min_test.hs:11:41: error:
    * Couldn't match expected type `a' with actual type `a1'
      `a1' is a rigid type variable bound by
        the type signature for:
          loop :: forall a1. (Bar a1, Foo a1) -> Bar a1
        at min_test.hs:10:13
      `a' is a rigid type variable bound by
        the type signature for:
          funct :: forall a. Bar a -> (a -> Foo a) -> Bar a
        at min_test.hs:7:10
    * In the first argument of `fn', namely `y'
      In the expression: fn y
      In the first argument of `loop', namely `(Bar y, fn y)'
    * Relevant bindings include
        y :: a1 (bound at min_test.hs:11:19)
        x :: Bar a1 (bound at min_test.hs:11:11)
        loop :: (Bar a1, Foo a1) -> Bar a1 (bound at min_test.hs:11:5)
        fn :: a -> Foo a (bound at min_test.hs:8:15)
        funct :: Bar a -> (a -> Foo a) -> Bar a (bound at min_test.hs:8:1)

TL; DR = GHC无法推断第7行类型签名中的a与第11行类型签名中的a相同。< / p>

如果我在第11行发表评论,那么每个人都很高兴。

问题

有没有办法为loop写一个类型签名,以便GHC / Haskell知道两个地方的a是一样的?

0 个答案:

没有答案