什么是在Haskell中使用警卫的优势?

时间:2017-03-14 14:23:14

标签: haskell

count_instances :: (Int)->([Int])->Int 
count_instances x [] = 0 
count_instances x (t:ts) 
    | x==t = 1+(count_instances x ts) 
    | otherwise = count_instances x ts

我只是想知道在这个问题中使用警卫有什么好处?

3 个答案:

答案 0 :(得分:3)

守卫可以只写一个if-then-else表达式的一半;你可以省略else并具有部分功能。

-- Leave the function undefined for x /= y
foo x y | x == y = ...

您可以使用case语句执行相同的操作,但它更详细

foo x y = case x == y of
          True -> ...

将几个不相关的条件列为一组替代条件比使用嵌套的if-then-elsecase表达式更容易。

foo x y | p1 x y = ...
foo x y | p2 x y = ...
foo x y | p3 x y = ...
foo x y = ...

VS

foo x y = if p1 x y then ... 
          else (if p2 x y then ...
                else (if p3 x y then ... else ...))

答案 1 :(得分:2)

警卫是haskell最常见的条件语句,就像其他语言中的if / then / else一样。

您的代码显示了计算列表内容等于给定参数的直接实现。这是了解haskell递归如何工作的一个很好的例子。

另一种实现方式是

count_instances :: Int -> [Int] -> Int
count_instances i = length . filter (==i)

重用Prelude模块中已有的函数。这个更短,可能更具可读性。

答案 2 :(得分:2)

带有警卫的模式可能是编写代码最简洁的方法,否则需要嵌套的case / if表达式。

where 子句适用于所有守卫右手边。这就是为什么你的例子可以更简洁:

count_instances :: (Int)->([Int])->Int 
count_instances x [] = 0 
count_instances x (t:ts) 
    | x==t = 1+rest 
    | otherwise = rest
    where rest = count_instances x ts