我有一个函数,它的工作是计算一些类型的最佳值a
wrt 一些类型的值函数a -> v
type OptiF a v = (a -> v) -> a
然后我有一个容器想要将这样的函数与另一个使用值的函数一起存储:
data Container a = forall v. (Ord v) => Cons (OptiF a v) (a -> Int)
这个想法是,任何实现类型函数的人OptiF a v
都不应该被它的细节所困扰,v
除非它是Ord
.
所以我写了一个函数,它接受这样一个值函数和一个容器。使用OptiF a v
它应该计算出最佳值 wrtval
并将其插入容器的result
函数中:
optimize :: (forall v. (Ord v) => a -> v) -> Container a -> Int
optimize val (Cons opti result) = result (opti val)
到目前为止一切顺利,但我不能打电话optimize
,因为
callOptimize :: Int
callOptimize = optimize val cont
where val = (*3)
opti val' = if val' 1 > val' 0 then 100 else -100
cont = Cons opti (*2)
不编译:
Could not deduce (v ~ Int)
from the context (Ord v)
bound by a type expected by the context: Ord v => Int -> v
at bla.hs:12:16-32
`v' is a rigid type variable bound by
a type expected by the context: Ord v => Int -> v at bla.hs:12:16
Expected type: Int
Actual type: Int
Expected type: Int -> v
Actual type: Int -> Int
In the first argument of `optimize', namely `val'
In the expression: optimize val cont
第 12:16-32 行在哪里optimize val cont
。
在这种情况下,我是否误解了存在类型?forall v
声明中的optimize
意思是否可以optimize
期望得到它想要的a -> v
任何东西?v
或者这是否意味着除此之外optimize
可能没有任何期望?a -> v
Ord v
我想要的是OptiF a v
any 不是固定的v
,因为我想a -> v
稍后插入一些。我想施加的唯一约束是Ord v
. 甚至可以使用存在类型(或其他)来表达类似的东西吗?
我设法通过一个额外的类型类来实现这一点,它提供了optimize
一个与OptiF a v
.