Haskell测试实践困在表和映射函数上

时间:2014-08-10 15:18:45

标签: haskell dictionary filter mapping

这是我的考试练习题中的问题:

The following table gives the names, grades and age of people employed by a 
company: 

Name       Grade     Age 
Able       Director  47 
Baker      Manager   38 
Charles    Trainee   19 
Dunn       Director  50 
Egglestone Manager   42 

i. Define a Haskell type suitable for representing the information in such a 
table [10%] 

A function avAge is required to find the average age of people in a given grade, 
for instance in the example the average age of managers is 40. Give three 
alternative Haskell definitions for this function: 

ii. using explicit recursion, [20%] 
iii. using mapping functions, [20%] 
iv. using list comprehensions. [20%]

表格不是很清楚,因为我无法粘贴正确的表格,但您基本上可以看到有3列和多行,一个用于名称,一个用于年级,一个用于年龄。因此,您可以看到第一个问题“i”是定义一个适合表示此类表中信息的haskell类型。保持我的真正的桌子当然有线条。

那么我该如何定义一个函数呢?定义一个函数意味着例如“[String] - > String - > Int”或者我必须写一个能做某事的函数?

最后,关于avAGe找到人们的平均年龄,用映射函数做背后的想法是什么?我已经计划用于显式递归,但我真的很难适应映射函数(map,foldr,filter等)。

1 个答案:

答案 0 :(得分:6)

合适的类型是每行具有数据类型的类型,也许您可​​以使用现有的集合类型来保存多行。为了让你开始:

data Entry = Entry __________ deriving (Eq, Show)
type Entries = __________

那么什么应该在空白?它需要能够拥有一个名字,一个年级和一个年龄。对于Entries,您应该能够使用内置类型来存储所有这些行,可能是按顺序排列。

等级是否来自固定数量的有效值?然后您可以考虑使用ADT来表示它们:

data Grade
    = Trainee
    | Manager
    | Director
 -- | AnyOtherNameYouNeed
    deriving (Eq, Show)

如果没有,那么你可以使用String s,但我仍然会给他们一个名字:

type Grade = String

现在您已经设置了类型,您可以处理avAge的实现。您需要显式递归,映射和列表理解。该函数需要EntriesGrade并返回与Grade匹配的年龄的平均值,因此类型签名应该是

avAgeRec :: Entries -> Grade -> Double
avAgeRec entries grade = __________

avAgeMap :: Entries -> Grade -> Double
avAgeMap entries grade = __________

avAgeComp :: Entries -> Grade -> Double
avAgeComp entries grade = __________

这应该可以帮助你开始,我只是不想给你答案,因为这是一个研究问题,自己提出答案总是更好=)


所以现在你有了

type Grade = String
type Entry = (String, Grade, Int)
type Entries = [Entry]

从以下评论中略微填写:

avAgeRec :: Entries -> Grade -> Double
avAgeRec entries grade = __________

avAgeMap :: Entries -> Grade -> Double
avAgeMap entries grade = <calculate average> $ map <get ages> $ filter <by grade> entries

avAgeComp :: Entries -> Grade -> Double
avAgeComp entries grade = __________

你现在可以获得更多空白吗?