Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Haskell 获取异构列表的最后一个元素_Haskell - Fatal编程技术网

Haskell 获取异构列表的最后一个元素

Haskell 获取异构列表的最后一个元素,haskell,Haskell,我试图定义一个函数(hLast),它返回异构列表的最后一个元素: 类型系列HLastR xs,其中 HLastR'[x]=x HLastR(x):xs)=HLastR-xs 类HLast xs,其中 hLast::HList xs->HLastR xs 实例HLast'[x]其中 hLast(x`HCons`HNil)=x 实例(HLast-xs,HLastR-xs~HLastR(x':xs))=>HLast(x':xs),其中 hLast(x`HCons`xs)=hLast xs 对于此代码

我试图定义一个函数(
hLast
),它返回异构列表的最后一个元素:

类型系列HLastR xs,其中
HLastR'[x]=x
HLastR(x):xs)=HLastR-xs
类HLast xs,其中
hLast::HList xs->HLastR xs
实例HLast'[x]其中
hLast(x`HCons`HNil)=x
实例(HLast-xs,HLastR-xs~HLastR(x':xs))=>HLast(x':xs),其中
hLast(x`HCons`xs)=hLast xs
对于此代码,GHC总是抱怨
HLast
存在重叠实例。我不明白这些实例怎么会重叠:多个元素的
HList
只匹配第二个实例,而单例应该只匹配第一个实例,因为第二个实例需要一个
HLast
实例作为尾部(
HNil
在单例情况下,没有实例)


在第一个实例中添加一个
{-#OVERLAPPING#-}
指令可以解决这个问题,但对于这样一个简单的问题来说,这感觉像是一个过于粗糙的解决方案。有更好的方法吗?谢谢

假设
HList
被定义为GADT,您首先不需要类型类

数据列表xs,其中
HCons::x->hlistxs->HList(x):xs
HNil::HList'[]
键入族HLastR xs,其中
HLastR'[x]=x
HLastR(x):xs)=HLastR-xs
hlast::HList xs->HLastR xs
hlast(HCons x HNil)=x
hlast(HCons_xs@(HCons_uxs))=hlast-xs

检查重叠时不考虑约束。这将需要实例解析程序执行回溯:例如,让我们尝试
HLast(x':[])
instance,这需要
HLast'[]
,但它不存在,所以让我们返回并尝试另一个
HLast'[x]
实例。它不是这样工作的,我们只是在不考虑约束的情况下选择最好的匹配头,盲目地向前冒险。我认为
HLast'[x]
HLast(x':y':xs)
应该可以工作。我明白了,那么我实际上更喜欢
{-#重叠#-}
解决方案。谢谢你的提示!我不是一个足够的类型级黑客专家,不想马上想出一个例子,但我怀疑
{-#OVERLAPPING#-}
在某些情况下会在列表只有一个元素时选择后一个实例。typechecker已经确定列表是一个cons,但是还没有关于尾部的信息(后来变成
[]
)。这更灵活,但是它有相当不同的内联行为。这需要权衡。