2016-05-16 165 views
0

你好哈斯克尔社区,哈斯克尔 - 布尔RoseTree

由于玫瑰树的通常的定义:

RoseTree a = Node a [RoseTree a] 

我一直在抓我的头在这个特定功能的实现:

boolRoseTree :: Blocks -> Blocks -> RoseTree a -> Bool 
boolRoseTree blocksA blocksB roseTree 

其中Blocks只是一个[Int],它总是包含6个大于或等于0的元素。 现在函数我希望实施检查blocksA的某个元素是否为某个值,并且blocksB的某个元素也是某个值,并且如果条件满足,则返回True。这是非常模糊的,所以允许我用一个例子阐明:

| (blocksA !! 0 == 1 || blocksA !! 0 == 10) && blocksB !! 1 /= 0 = True

即如果的blocksA所述第一元素是110blocksB所述第二元件不0,然后返回True。我希望对blocksA的所有元素都这样做,但是每次元素增加+1。通过我的意思是下一个警卫将是:

| (blocksA !! 1 == 2 || blocksA !! 1 == 11) && blocksB !! 2 /= 0 = True 
| (blocksA !! 2 == 3 || blocksA !! 2 == 12) && blocksB !! 3 /= 0 = True 
| (blocksA !! 3 == 4 || blocksA !! 3 == 13) && blocksB !! 4 /= 0 = True 
| (blocksA !! 4 == 5 || blocksA !! 4 == 14) && blocksB !! 5 /= 0 = True 

很显然,我可以警卫一长串代码本,通过所有blocksA !! 0blocksA !! 1blocksA !! 2blocksA !! 3blocksA !! 4blocksA !! 5最终达到一个otherwise声明往哪个返回False。然而,这可以通过玫瑰树更有效地实现(我认为)。

我想在玫瑰树的第一层必须有六个节点,0到5代表树的元素。然后,每个节点都必须有2个值,这两个值是我想要的blocksA在列表的特定元素处的两个值 - 但是,我也不得不检查blocksB的对应元素是否不为零。

我真的不知道从哪里开始像这样的问题......任何帮助将不胜感激。

+0

我编辑了你的问题,希望问题现在在语法上有效。但我仍然没有看到玫瑰树与此有什么关系。 –

回答

1

不知道怎么玫瑰树就在这里工作,但对于这个 数据结构:

checks = 
    [ ((0,0), [ (1, 10, 1) , (2, 11, 2) , (3, 12, 3) , (4, 13, 4) , (5, 14, 5) ]) 
    , ((1,..), [ ... ] 
    , ((2,..), [ ... ] 
    , ... 
    , ((5,..), [ ... ] 
    ] 

这里是如何解构它:

[ ((0,0) [ (1, 10, 1) , (2, 11, 2) , (3, 12, 3) , (4, 13, 4) , (5, 14, 5) ] 
    i z  x y j  x y j  x y j  ... 

每组值i,z,x,yĴ对应 后卫:

| ((a !! i) == x || (a !! i) == y) && (b !! j /= z) = True 

要执行所有的检查,只用一个列表理解:

func :: [Int] -> [Int] -> Bool 
func a b = or $ do ((i,z), triples) <- checks 
        (x,y,j) <- triples 
        return $ ((a !! i) == x || (a !! i) == y) && (b !! j /= z) 

所有的单子元素都是或-ED一起。由于懒惰,只要遇到第一个True检查,函数将返回True。

+0

Willem Van Onsem - 对语法失败表示歉意。 @ErikR - 事后看来,我想我正在尝试做一些你不能做的事情。感谢您的帮助。 –