2012-09-14 13 views
0

我有拉链,在当前元素可以有不同的类型的左侧和右侧列表玩弄周围:期广义方法与不同类型的当前元素和左/右列表

data Z a b = Z ([a], b, [a]) 

一可以与moveLeftmoveRight导航拉链:

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 

,一切都按预期工作,真好!

我想什么,现在要做的就是推广上述理念,使得通过仅实现对于给定的Z a blistF功能currentF(比如a :: Charb :: Int),moveLeftmoveRight做正确的事情自动的。什么是正确的方法来做到这一点?

我试图实现这样一个类:

class CPos a where 
    listF :: c -> d -> d 
    currentF :: d -> c -> c 
    moveLeft :: a -> a 
    moveRight :: a -> a 

其中moveLeft/Right都在listFcurrentF方面实现,但这种失败

The class method `listF' mentions none of the type variables of the class CPos a 

备注2

的东西我不喜欢,一般上面的想法是,要允许任意函数listFcurrentF这是不可能保证

moveLeft . moveRight = id 

的事实(如拉链是否在名单内,上边界这反正不成立)。任何提示强制执行此?

+0

重申您的第二条评论:将其记录为“CPos法律”。 C.F. [Functor laws](http://www.haskell.org/ghc/docs/latest/html/libraries/base/Data-Functor.html#t:Functor),[Monoid laws](http://www.haskell .org/ghc/docs/latest/html/libraries/base/Data-Monoid.html#t:Monoid)等。 – dave4420

回答

1

这是一个解决方案。我不认为你可以执行moveLeft . moveRight = id。我的意思是保证两个功能是平等的是不可判定的。你所能做的最好的就是写quickcheck测试用例来保证相同。

相关问题