2015-08-13 27 views
2

我是Haskell noob,在阅读关于Haskell Road中的含义时,我来到了下面的难题。有没有用于防护分析的工具?

verdict :: Bool -> Bool -> (Bool, String) 
verdict p q | not result = (False, "LIAR") 
      | result && p = (True, "telling the truth") 
      | result  = (True, "innocent unless proven guilty") 
      | otherwise = (False, "we shouldn't get here") 
    where result = (not p) || q 
-- map (\x -> verdict (fst x == 1) (snd x == 1)) [(1,1),(1,0),(0,1),(0,0)] 

是否有一种工具可以警告我有关其他或其他类似的逻辑错误?

+1

请注意,您的'否则'子句真正无法访问:在'not result'和'result'之间涵盖了所有可能性。 – duplode

回答

8

我想我会写这个函数以不同的方式:

-- not result 
verdict True False = (False, "LIAR") 
-- result && p 
verdict True True = (True , "telling the truth") 
-- result 
verdict False _  = (True , "innocent unless proven guilty") 
verdict _  True = (True , "innocent unless proven guilty") 
-- otherwise 
verdict _  _  = (False, "we shouldn't get here") 

那么它不仅是明显的,其条款可以去掉(过去两年)人,也让机器; ghc其默认警告级别这样说:

test.hs:2:5: Warning: 
    Pattern match(es) are overlapped 
    In an equation for ‘verdict’: 
     verdict _ True = ... 
     verdict _ _ = ... 

检查后卫重叠,一般当然是不可判定的;此外我不知道一个工具会尝试给出一个近似的答案。

+0

啊!我想,我在暗示问题上被困了两天。但最终它变得非常有启发性。 –

4

这可能是你的意图更清晰的表达:

implies :: Bool -> Bool -> Bool 
p `implies` q = not p || q -- The backticks allow infix usage. 

-- The assumption is that p `implies` q is a known fact. 
verdict :: Bool -> Bool -> (Bool, String) 
verdict p q = (result, remark) 
    where 
    result = p `implies` q 
    remark 
     | not result = "LIAR" 
     | p = "telling the truth" 
     | otherwise = "innocent until proven guilty" 

卫队是语法糖图案Bool值相匹配。有关排列模式匹配的一般技巧,请参阅Daniel Wagner的答案。

+0

“隐含”在中缀/运算符形式中会更好。 –

+0

@ErikAllik它会,但我想避免语法变体超载。不过,虽然如此,但我认为采纳你的建议不会有什么坏处。 – duplode

相关问题