非详尽模式

时间:2018-09-16 01:31:18

标签: haskell

我对Haskell还是陌生的,我有一个问题。我有一个模块定义为:

inc :: Int->[Int]->[Int]

应该做的是在第二个参数中返回所有出现的第一个参数。因此,1 [1,1,3]的输出将返回[1,1]

这就是我所拥有的:

 inc :: Int->[Int]->[Int]
 inc x [y] = if [x] == [y] then [x] else []

由于我一直在苦苦挣扎,所以我只想看看它是否对一个数字有效,是否可以。例如:1 [1]返回[1]。但是,当我尝试使用多个值(例如1 [1,1])时,会收到错误消息:

  

函数inc中的非穷举模式

我该如何调整我的程序,使其能够处理多个值而不是一个值?

4 个答案:

答案 0 :(得分:1)

列表值可以采用以下任意一种形式

  • []
  • [y1],即y1:[]
  • [y1,y2],即y1:y2:[]
  • [y1,y2,y3],即y1:y2:y3:[]
  • ...
  • 无限列表y1:y2:y3:...

(很有趣的是,我们也有以结尾结尾的列表,但我会忽略它们)

一个定义方程,例如

f [y] = ...

仅考虑格式为[y1]且具有单个元素(y)的列表。其他所有情况都不与方程式匹配。

如果y是通用列表参数,而不是单个元素,则必须使用

f y = ...

我们看到,列表参数不需要特殊的语法。

要检测非穷举性错误,强烈建议在编译过程中打开警告。如果这样做,GHC将报告我们错过了案例[]_:_:_,后者是至少包含两个元素的列表。

答案 1 :(得分:0)

您的实现是不完整的,它表示您仅支持单个元素的列表。您需要扩展实现以涵盖所有可能性。使用递归遍历所有元素。可能的实现方式可能是:

inc :: Int->[Int]->[Int]
inc _ [] = []
inc x (y:ys) = if x == y then x:inc x ys else inc x ys

答案 2 :(得分:0)

当您要检查某种类型的值时,您需要知道该类型可能的“形状”(即数据构造函数)是什么。

对于列表,值具有以下两种形式之一:

  • 空:[]
  • 非空:h : t(其中h是列表的头(第一个元素),t是列表的头(另一个列表))

当您编写类似[1, 2, 3]的内容时,它的实际含义是1 : (2 : (3 : []))(一个列表的头为1,其尾部是另一个列表,其头为2,其尾部是另一个列表,其头是3,尾是[])。

对于使用列表的函数,通常意味着您需要提供两个方程式:

inc x [] = ...

处理空列表和

inc x (y : ys) = ...

处理非空列表(y是列表的第一个元素,ys是其余值)。

答案 3 :(得分:0)

在Haskell中,尽可能避免显式递归,并通过使用函数消除一些详尽的模式匹配。专门针对这种情况,您可以使用- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath { NSDate *selectedDate = [self.calculator dateForIndexPath:indexPath]; FSCalendarMonthPosition monthPosition = [self.calculator monthPositionForIndexPath:indexPath]; FSCalendarCell *cell; if (monthPosition == FSCalendarMonthPositionCurrent) { cell = (FSCalendarCell *)[collectionView cellForItemAtIndexPath:indexPath]; } else { cell = [self cellForDate:selectedDate atMonthPosition:FSCalendarMonthPositionCurrent]; NSIndexPath *indexPath = [collectionView indexPathForCell:cell]; if (indexPath) { [collectionView selectItemAtIndexPath:indexPath animated:NO scrollPosition:UICollectionViewScrollPositionNone]; } } if (![_selectedDates containsObject:selectedDate]) { cell.selected = YES; [cell performSelecting]; } [self enqueueSelectedDate:selectedDate]; [self.delegateProxy calendar:self didSelectDate:selectedDate atMonthPosition:monthPosition]; [self selectCounterpartDate:selectedDate]; } 。阅读其文档here

使用此功能,您的程序可以编写为:

filter

或自由点样式:

inc :: Int-> [Int] -> [Int]
inc x ys = filter (==x) ys