Haskell 如何告诉类型检查器绑定中的类型签名与顶级类型签名匹配?
背景 我喜欢在我的Haskell 如何告诉类型检查器绑定中的类型签名与顶级类型签名匹配?,haskell,typechecking,parametric-polymorphism,Haskell,Typechecking,Parametric Polymorphism,背景 我喜欢在我的where和绑定中添加类型签名,因为它可以帮助我记住我需要的结果和输入内容。它还可以帮助类型检查器在我出错时给我一条清晰的错误消息。但是,它最近给我带来了一些问题: 给定的 这是一个公认的精心设计的最低限度的例子: data Foo a = Foo a | NotFoo -- 3 -- 4 data Bar a = Bar a
where
和绑定中添加类型签名,因为它可以帮助我记住我需要的结果和输入内容。它还可以帮助类型检查器在我出错时给我一条清晰的错误消息。但是,它最近给我带来了一些问题:
给定的
这是一个公认的精心设计的最低限度的例子:
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
相同
如果我把第11行注释掉,每个人都很高兴
问题
有没有一种方法可以让GHC/Haskell知道a
在两个地方都是相同的a
来为loop
写一个类型签名?怎么样?