使Haskell List Recursion函数更有效

时间:2016-01-28 18:25:47

标签: list haskell recursion boolean pattern-matching

我编写了一个函数,它将比较两个列表并检查第一个是否是第二个的前缀,并且必须使用递归完成。

例如:

prefix [1,2] [1,2,3]
>True
prefix [2,1,4] [2,1,13,4]
>False

现在我已经完成了这项工作,但我觉得效率很低:

prefix :: [Int] -> [Int] -> Bool
prefix (x:xs) (y:ys)
|   null xs                         =   True
|   x == y && head xs == head ys    =   True && prefix xs ys
|   head xs /= head ys              =   False

我希望能够更高效地完成并使用更好的模式匹配。可以吗?

3 个答案:

答案 0 :(得分:5)

您根本不需要使用head功能。这使得比较的数量增加了一倍。试试这个:

prefix :: [Int] -> [Int] -> Bool
prefix [] _ = True
prefix _ [] = False
prefix (x:xs) (y:ys)
  | x == y = prefix xs ys
  | otherwise = False

答案 1 :(得分:2)

Chad Gilbert的解决方案可以非常简化:

prefix :: [Int] -> [Int] -> Bool
prefix [] _ = True
prefix (x:xs) (y:ys)
  | x == y = prefix xs ys
prefix _ _ = False

这不会影响性能,但它会演示语言功能:当模式上的所有警卫都失败时,该匹配将被放弃,匹配将以下一个模式恢复。

答案 2 :(得分:0)

 Prelude > let prefix [] _ = True
 Prelude |     prefix _ [] = False
 Prelude |     prefix (x:xs) (y:ys) = if ( x==y) then prefix xs ys else False

示例:

  Prelude> prefix [1,3] []
  False
  Prelude> prefix [] [1,2,3]
  True
  Prelude> prefix [1,2] [1,2,3]
  True