我正在玩弄拉链,其中当前元素可以具有与左右列表不同的类型:
data Z a b = Z ([a], b, [a])
moveLeft
可以使用和浏览拉链moveRight
:
moveLeft :: (b -> a -> a) -> (a -> b -> b) -> Z a b -> Z a b
moveLeft listF currentF (Z (x:xs, c, ys)) = Z (xs, g x c, ((f c x):ys))
moveRight :: (b -> a -> a) -> (a -> b -> b) -> Z a b -> Z a b
moveRight listF currentF (Z (xs, c, y:ys)) = Z (((f c y):xs), g y c, ys)
在这里,listF
将列表元素和当前元素转换为左侧或右侧的列表元素。currentF
将当前元素和列表元素转换为当前元素。
如果当前类型和列表类型相等,则移动很简单:
moveLeftSameType :: Z a a -> Z a a
moveLeftSameType = moveLeft const const
一切都按预期工作,很好!
我现在想做的是概括上述想法,这样只需为给定的(比如, )实现listF
andcurrentF
函数,并自动做正确的事情。这样做的正确方法是什么?Z a b
a :: Char
b :: Int
moveLeft
moveRight
评论
我试图实现这样的类:
class CPos a where
listF :: c -> d -> d
currentF :: d -> c -> c
moveLeft :: a -> a
moveRight :: a -> a
wheremoveLeft/Right
是根据listF
and实现的currentF
,但这失败了
The class method `listF' mentions none of the type variables of the class CPos a
备注 2
我一般不喜欢上述想法的一点是允许任意函数listF
并且currentF
无法保证
moveLeft . moveRight = id
(如果拉链在列表中,则在边框上无论如何都不存在)。执行此操作的任何提示?