给出
data Allocation =
Alloc [(Var, Register)]
deriving (Eq, Show)
instance Ord Allocation where
Alloc a < Alloc b = .......
如果Allocation
的不同寄存器少于Allocation
,我想知道一个Alloc a
是否优于另一个Alloc b
。
我认为我可以使用一些方法/策略,但不知道如何将它们串在一起。
snd 可以从(Var,Register)元组中取出寄存器
nub 可以删除列表中的重复项
长度表示列表的长度
相交以查找两个列表之间的交集
尝试从(Var, Register)
和Alloc a
的{{1}}元组中提取寄存器。也许找到两个列表的交集,从两个列表中删除它们,并比较剩余的长度。如果长度Alloc b
大于长度a
,则b
是更好的长度。否则,它是a
。
我是否在思考这个问题,还是我在某种程度上走上正轨?
编辑:以下是我的尝试
b
所以我的助手有效,但现在的问题是如何从列表中删除列表,以便helper :: Allocation -> [Register]
helper (Alloc a) = nub (map snd a)
instance Ord Allocation where
Alloc a < Alloc b = length (helper a - (helper a `intersect` helper b)) < length (helper b - (helper a `intersect` helper b))
删除a
和a
和b
交叉的所有内容{1}}也会这样做。
答案 0 :(得分:1)
我很有可能误会,但我认为你可能会让它过于复杂。每个分配是变量和寄存器对的列表,分配使用的不同寄存器的数量与它与之比较的分配无关。因此,我不确定我理解你为什么要做交叉。
如果我理解你正在尝试做什么,定义Ord
实例最简洁的方法就是这样:
instance Ord Allocation where
compare = comparing (length . nub . map snd . assignments)
where assignments (Allocation a) = a
在这里,我们为compare
的每个操作数:
然后我们比较这两个数字,确定哪个更好。如果您不允许使用comparing
,则可以内联其相对较短的definition。