【发布时间】:2011-06-21 03:41:50
【问题描述】:
我正在处理 yesod 中的一个复杂函数。它在 where 部分有很多没有类型的函数,但类型检查正确。我决定尝试添加一些类型签名,这样我就可以一次弄清楚发生了什么,但是添加类型签名会导致类型错误。
所以我将函数缩减为一个简单的案例来发布在这里,它仍然给出了一个我不明白的类似错误。
helper :: [(String, a)] -> [(Int, a)]
helper xs = blah
where
blah :: [(Int, a)]
blah = zip [1..10] (map snd xs)
如果我从 blah 中删除类型签名,它编译得很好,但如果我添加该类型签名,它会给我错误:
Couldn't match type `a' with `a1'
`a' is a rigid type variable bound by
the type signature for helper :: [(String, a)] -> [(Int, a)]
at Blah.hs:4:1
`a1' is a rigid type variable bound by
the type signature for blah :: [(Int, a1)] at Blah.hs:7:5
Expected type: [(String, a1)]
Actual type: [(String, a)]
In the second argument of `map', namely `xs'
In the second argument of `zip', namely `(map snd xs)'
- 我也不知道为什么在进行类型检查时,助手中的“a”被解释为与助手不同的“a”。
- 为什么它甚至会关心 a 是否不同
- 我不知道如何确定 blah 实际是什么类型,因为我无法在仍使用其参数的同时将其移至顶层。
编辑:
好的,在我将此标记为已回答之前,我还要进行一次编辑。在我使用的代码中,有一些约束(Eq a,Monad monad)=> 等等,等等等等,所以我的解决方案不太奏效。所以我正在修改我的示例代码以更接近真实代码:
helper :: (Eq a, Num b) => b -> [(String, a)] -> (b, [(Int, a)])
helper b xs = (b+b, blah)
where
blah :: [(Int, a)]
blah = filter (\y -> fst y == 11) $ zip [1..10] (map snd xs)
如果我放
helper :: forall a. (Eq a, Num b) => b -> [(String, a)] -> (b, [(Int, a)])
这不起作用,因为(我假设因为 b 不在范围内,但我无法弄清楚将 forall b 放入此类型的语法。(forall a,forall b 不起作用,forall a, b 不起作用)。
【问题讨论】:
标签: haskell