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
我只是想知道在这个问题中使用警卫有什么好处?
答案 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-else
或case
表达式更容易。
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