首先,我创建了一个Type StudentMark,它是一个元组,首先是一个字符串,然后是一个Int .
type StudentMark = (String, Int)
这是我的capMarks功能:
capMarks :: [StudentMark] -> [StudentMark]
capMarks [cMarks] = [(st, mk) | (st, mk) <- [capMark cMarks]]
这是我的capMark功能:
capMark :: StudentMark -> StudentMark
capMark (st, mk)
| mk > 39 = (st, 40)
| mk < 40 = (st, mk)
它应该返回:
[("Jo", 37), ("Sam", 40)]
从:
capMarks [("Jo", 37), ("Sam", 76)]
但是当我只在函数中输入1个参数时,只返回正确和预期的响应,例如:
capMarks [("Jake", 50)]
要么
capMarks [("Jake"), 30]
但是使用两个(或更多)它应该告诉我capMarks函数中有一个非详尽的模式 .
2 回答
让我们分析你的
capMarks
函数:首先
capMarks [cMarks] = ...
是模式匹配 . 这匹配包含单个元素的列表 . 我假设您想要对整个列表执行某些操作,因此请将此更改为capMarks cMarks = ...
接下来
... [(st, mk) | (st, mk) <- [capMark cMarks]]
将capMark
函数应用于原始模式匹配方案中的唯一元素,然后将结果作为列表的唯一元素 . 您似乎希望将capMark
应用于列表的每个元素 . 因此,如果我们遵循先前的建议,您需要执行类似... [capMark mark | mark <- cMarks]
的操作 . 这完全如前所述:将capMark
应用于cMarks
列表的每个元素 .最终版本:
或者,您也可以使用模式匹配和显式递归:
第一行表示应用于空列表的
capMarks
是一个空列表 . 第二行表示capMarks
适用于具有至少一个元素的列表将capMark
应用于第一个元素,然后递归地将capMarks
应用于列表的其余部分 .这是Haskell中的一种常见模式,即有一个名为
map
的函数可以对其进行概括 . 使用map
非常简单:map
的类型为(a -> b) -> [a] -> [b]
,这意味着它需要一个函数和一个列表并返回一个列表 . (a
和b
只告诉编译器哪些类型必须相同 . )_ _182432_然后将函数应用于输入列表中的每个元素 .最后,您将了解部分功能应用和无点样式 . 使用这两个概念,使用
map
的版本可以略微简化:不要太担心这个 . 我只是为了完整而添加它 .
您应该检查模式匹配在Haskell中的工作方式 .
capMarks [x]
仅匹配具有一个元素的列表 . 您可能想要的是capMarks myList = [ ... | ... <- f myList]
或以递归方式定义案例的休止符 .例如
这个简化的“版本”在拥抱中起作用