【发布时间】:2020-01-17 00:52:35
【问题描述】:
在我的实际问题中,我有一个函数f,作为参数传递,它会更改列表中的顺序,但对类型没有要求,也不会更改类型。我想在[Int] 和[Bool] 上应用该函数,所以我必须解决两个上下文,试图将f 类型转换为[Int] -> [Int] 或[Bool] -> [Bool]。我用Rank2Types 解决了这个问题。
但后来我在f 和any 等函数列表上使用any 要求函数为[a] -> [a] 而不是forall a. [a] -> [a]。
下面的代码虽然荒谬,但完美地重现了错误:
{-# LANGUAGE Rank2Types #-}
--debug :: (forall a. [a] -> [a]) -> Bool
debug swap = any combine [swap]
where
combine :: (forall a. [a] -> [a]) -> Bool
combine f = usefonBool f && usefonInt f
--usefonBool :: (forall a. [a] -> [a]) -> Bool
usefonBool f = f [True,True] == [False]
--usefonInt :: (forall a. [a] -> [a]) -> Bool
usefonInt f = (f [1,2]) == [2,1]
错误信息是:
• Couldn't match type ‘a’ with ‘forall a1. [a1] -> [a1]’
‘a’ is a rigid type variable bound by
the inferred type of debug :: a -> Bool
at /path/debug.hs:(4,1)-(12,36)
Expected type: a -> Bool
Actual type: (forall a. [a] -> [a]) -> Bool
• In the first argument of ‘any’, namely ‘combine’
In the expression: any combine [swap]
In an equation for ‘debug’:
debug swap
= any combine [swap]
where
combine :: (forall a. [a] -> [a]) -> Bool
combine f = usefonBool f && usefonInt f
usefonBool f = f [True, ....] == [False]
usefonInt f = (f [1, ....]) == [2, ....]
• Relevant bindings include
swap :: a (bound at /path/debug.hs:4:7)
debug :: a -> Bool (bound at /path/debug.hs:4:1)
|
我的目标是找到一个注释,让我可以在不同的类型上使用 f,然后在此类通用函数的列表中应用任何类型。
如果我取消注释我所有的类型注释(或只是顶部的注释),错误将变为
• Couldn't match type ‘[a0] -> [a0]’ with ‘forall a. [a] -> [a]’
Expected type: ([a0] -> [a0]) -> Bool
Actual type: (forall a. [a] -> [a]) -> Bool
• In the first argument of ‘any’, namely ‘combine’
In the expression: any combine [swap]
In an equation for ‘debug’:
debug swap
= any combine [swap]
where
combine :: (forall a. [a] -> [a]) -> Bool
combine f = usefonBool f && usefonInt f
usefonBool :: (forall a. [a] -> [a]) -> Bool
usefonBool f = f [True, ....] == [False]
....
|
【问题讨论】:
-
你为什么要注释掉类型签名?
-
@leftaroundabout 我将它们注释掉以展示一个尽可能少假设的版本。
-
这样不行。 GHC 只能推断 Rank-1 类型,因此您必须使用显式签名。在这种情况下,顶级的应该足够了。 – 但无论如何,省略签名通常是个坏主意。
-
@leftaroundabout 取消注释 my 顶级签名尚未解决
标签: haskell types type-inference