在我的实际问题中,我有一个作为参数传递的函数
错误信息是:
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]
....
|