我已经得到了他们的工作是计算型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
应该计算最优值WRT val
,并在容器的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
。
我误解了这种情况下的存在类型? optimize
声明中的forall v
是否意味着optimize
可能期望从a -> v
什么v
它想要什么?或者这是否意味着optimize
可能对a -> v
期待什么,除了Ord v
?
我想要的是OptiF a v
不是固定的任何v
,因为我想稍后插入一些a -> v
。我想强加的唯一约束是Ord v
。甚至可以用存在类型(或其他)来表达类似的东西?
我设法实现了与一个额外的typeclass,它提供optimize
函数与OptiF a v
类似的签名,但看起来比使用高阶函数更丑陋。
你让我的一天,也许是接下来的几个:)你是什么意思'存在过时'?它们被GADT包含在http://en.wikibooks.org/wiki/Haskell/GADT#Existential_types中。但是,我不应该在不需要GADT的情况下替换ADT,对吧? – chs 2013-02-28 15:38:57
对于简单的构造函数(但可能是许多不同的),旧的'data'语法可以说是更具可读性的,所以:不,你不应该用GADT代替它们(虽然它没有错!)。对于任何涉及数据头中未提及的类型变量的内容,我都会使用GADT语法。 – leftaroundabout 2013-02-28 16:00:24