首页 > 解决方案 > 我正在尝试在 haskell 中重新定义产品定义。我收到一条错误消息,提示“功能中的非详尽模式”

问题描述

product' :: [Integer] -> Integer
product' (x:xs)
  | (x:xs) == []   = 1
  | otherwise = x * (product' (xs))

第一个不起作用并给出错误。下面的一个使用模式匹配技术并且工作正常。

productP :: [Integer] -> Integer
productP [] = 1
productP (x:xs) = x * (productP (xs))

标签: haskellrecursionpattern-matching

解决方案


(x:xs) == []部分是无意义的:与(x:xs)构造一个包含至少一个元素的列表:x作为第一个元素,并xs作为剩余元素的(可能为空的)列表。因此,这将始终导致False.

模式的要点(x:xs)是它匹配非空列表。列表定义为:

data [a] = [] | (a:[a])  -- pseudo-code

因此,列表有两个数据构造函数:

  1. 空列表[];和
  2. (x:xs)有一个 headx和一个 tail的“缺点” xsx是列表的一个元素,并且xs是剩余元素的列表。

您可以检查xs整个列表是否等于空列表,然后使用headand tail

product' :: [Integer] -> Integer
product' xs
  | xs == []  = 1
  | otherwise = head x * product' (tail xs)

但是上面不是很优雅,因为headtail是非全部函数(它们对于空列表会出错),因此“更难”确定这个函数总是会产生答案。


推荐阅读