我对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中的非穷举模式
我该如何调整我的程序,使其能够处理多个值而不是一个值?
答案 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