`分组 teamNumber` 的类型
仔细看看类型grouping :: Int -> [Student]->[(Team, Student)]
,以及为其声明而声明的参数
grouping :: Int -> [Student]->[(Team, Student)]
grouping teamNumber = ...
返回类型是什么(等号右侧的类型)如果grouping
是否提供了等号左侧列出的所有参数?
Answer
等号右侧的类型是[Student]->[(Team, Student)]
。在 Haskell 中,接受两个参数并返回结果的函数可以等效地视为或定义为接受第一个参数并返回 a 的函数(接受第二个参数并返回结果的函数)。所以我们可以说,例如,表达式
grouping 3 :: [Student]->[(Team, Student)]
(grouping 3)
是一个函数,它获取学生列表并返回这些学生的列表,标记为 3 组。大概,如果(grouping 3)
应用于您示例中的学生列表,我们会
(grouping 3) [ 'Mark' , 'Hanna' , 'Robert' , 'Mike' , 'Jimmy' ] =
[(1,'Mark'),(2,'Hanna'),(3,'Robert'),(1,'Mike'),(2,'Jimmy')]
`zip ys` 的类型
柯里化与以下类型和表达式有什么关系?
zip :: [a] -> [b] -> [(a, b)]
zip ys
什么类型的zip ys
例如,如果ys :: [Bool]
?
这和你的问题有什么关系?
当您将其与类型一起考虑时grouping teamNumber
,这如何告诉你什么类型ys
需要在你的锻炼中吗?
把它们放在一起
从练习代码(忽略类型和where
条款)我们有:
grouping teamNumber = zip ys
只能有两件事=
在 Haskell 中,如果它们的类型能够统一。在这种情况下,类型grouping teamNumber
必须与类型相统一zip ys
.
从第一部分我们知道,grouping teamNumber
is [Student]->[(Team,Student)]
.
从第二部分我们知道zip ys
有类型[b] -> [(a, b)]
, where a
是这样一种类型ys
有类型[a]
.
因此,我们知道(~
是 Haskell 中的类型相等)
[Student]->[(Team,Student)] ~ [b] -> [(a, b)]
如果我们用以下内容替换类型变量,这些将统一b
and a
b ~ Student
a ~ Team
现在,我们知道了类型ys
is [a]
,如果我们进行相同的替换,则为[Team]
.
因此,如果满足以下条件,类型将是正确的:ys :: [Team]
.
结论
如果您能提供一个ys :: [Team]
,您可以生成一个从学生到标记有其团队的学生的函数([Student]->[(Team,Student)]
)通过传递ys
作为第一个参数zip
。这样的函数正是grouping
当它应用于单个参数时需要返回,teamNumber :: Int
.