【问题标题】:Haskell List Duplicates (if possible with map, elem and foldr)Haskell 列表重复项(如果可能,使用 map、elem 和 foldr)
【发布时间】:2019-11-24 16:59:19
【问题描述】:

我的任务是接收数据并“过滤”出每个重复项,如下例所示。如果可能,我必须使用函数 map、elem 和 foldr 老实说,我不知道该怎么做,如果有人能告诉我如何解决这个问题,我将不胜感激。

type StudentName = String
type CourseName  = String
type ExamScore   = (CourseName, Float)
type StudentData = [(StudentName, [ExamScore])]

students :: StudentData
students = [
 ("Tim Berners-Lee", [("Maths", 1.3), ("Algorithm", 2.0)]), 
 ("Ada Lovelace",[("Info 1", 3.0), ("Lambda-Maths", 1.7), ("Science", 2.3), ("Data Mining", 2.7)]),
 ("Alan Turing", [("Maths", 1.7), ("operatingSystems", 2.0), ("Lambda-Maths", 1.7)]),
 ("Alonzo Church", [("Info 2", 2.7), ("Systems", 2.3), ("Lambda-Maths", 1.0), ("Algorithm", 3.0)]),
 ("Bjarne Stroustrup", [("Info 1", 2.7), ("Info 2", 1.3), ("operatingSystems", 2.0), ("Topology", 2.3)]),("Bjarne Stroustrup", [("Info 1", 2.7), ("Info 2", 1.3), ("operatingSystems", 2.0), ("Topology", 2.3)]),
 ("Donald E. Knuth", [("Maths", 3.3), ("Info 2", 1.7), ("Lambda-Maths", 2.0), ("Science", 4.0)]),
 ("Grace Hopper", [("Info 3", 1.0), ("operatingSystems", 2.3), ("Systems", 1.7)]),
 ("Annie Easley", [("Maths", 1.0), ("Info 2", 1.7)]),
 ("Edsger W. Dijkstra", [("Topology", 3.3), ("Algorithm", 2.7), ("Systems", 4.0)]),
 ("John von Neumann", [("Maths", 3.3), ("Algoritmische Topologie", 1.0), ("operatingSystems", 1.3), ("Systems", 5.3)])
 ]

courses :: [CourseName]
courses = ["Maths", "Info 1", "Info 2", "Algorithm", "operatingSystems", "Topology", "Lambda-Maths", "Systems", "Science", "Data Mining"]

examResults :: [ExamScore]
examResults = [("Maths", 3.3), ("Topology", 1.0), ("operatingSystems", 1.3), ("Systems", 5.3), ("Info 1", 1.7), ("Info 2", 1.7), ("Data Mining", 0.3)]





filterDuplicates :: StudentData -> StudentData
filterDuplicates



--e.g.
-- filterDuplicates [("Tom", [("Course A", 1.3), ("Course B", 2.0)]), ("Tom", [("Course A", 1.3), ("Course B", 2.0)])]
-- output: [("Tom", [("Course A", 1.3), ("Course B", 2.0)])]

【问题讨论】:

    标签: haskell


    【解决方案1】:

    在解决这个问题之前,你需要对elemmapfoldr函数有一个很好的了解。 (编辑:也许你不需要filter。我最初将foldr 读作filter,但该部分中有一些有用的细节会有所帮助,所以我离开了。

    元素

    如果你有一些编程经验,elem 应该不难。在 Haskell 中学习新函数时,我们通常从类型签名开始,因为它可以为我们提供大量信息。对于elem,它是a -> [a] -> Bool。这意味着它有两个参数,一个a 类型的值和一个a 类型的值列表,然后它返回一个Bool。如果值在列表中,则返回True,否则返回False

    > elem 1 [1,2,3]
    True
    > elem "car" ["boat","bus","airplane"]
    False
    

    在许多 Haskell 代码中,您可能会看到 elem 通过将其包裹在反引号中而以中缀样式使用。

    > 1 `elem` [1,2,3]
    True
    > "car" `elem` ["boat","bus","airplane"]
    False
    

    过滤

    我们再次从类型签名开始。对于filter,它是(a -> Bool) -> [a] -> [a]filter 接受两个参数,(a -> Bool) 是一个函数f,它接受一个a 类型的参数并返回一个Bool[a] 是一个a 类型的值列表。它将评估列表中每个值的函数f。当f 返回False 时,它将忽略该项目,当f 返回True 时,它将收集它并将其添加到它返回的新列表中。这里有一些例子。

    > even [1,2,3,4,5,6]
    [2,4,6]
    > odd [1,2,3,4,5,6]
    [1,3,5]
    

    在我们继续之前,了解什么是 lambda 函数(也称为匿名函数)会很有帮助。它们是一种定义函数而不给函数命名的方法。它还让我们在线定义一个函数。语法类似于(\x -> ...),其中x 是我们传入的参数的名称,... 应替换为函数体。现在让我们尝试为filter 定义一些lambda 函数(记住它们必须返回Bool)。

    -- keep numbers greater than zero
    > filter (\x -> x > 0) [-1,-2,3,5,0,-4,100] 
    [3,5,100]
    -- keep lists (Strings) longer than 3
    > filter (\x -> length x > 3) ["the", "a", "hello", "goodnight", "bye"]
    ["hello", "goodnight"]
    

    地图

    最后map 有一个看起来像(a -> b) -> [a] -> [b] 的类型签名。 (a -> b) 是一个函数f,它接受a 类型的值并返回b 类型的值,[a]a 类型值的列表,然后它返回[b] 这是[b] 类型的值列表。它对列表中的每个值评估函数f 并返回具有相同数量元素的列表,但值可能会更改。下面是几个例子。

    -- here type a is Int and type b is also Int
    -- add one to every element in the list
    > map (\x -> x + 1) [1,2,3,4]
    [2,3,4,5]
    
    -- here type a is String and type b is also String
    -- append a "." to every String in the list
    > map (\x -> x ++ ".") ["hello", "goodbye"]
    ["hello.", "goodbye."]
    
    -- here type a is String and type b is Int
    > map (\x -> length x) ["hello", "goodbye"]
    
    -- here type a is Int and type b is String
    > map (\x -> show x) [1,2,3,4]
    ["1","2","3","4"]
    

    文件夹

    foldr 有点复杂。它的列表类型签名是 (a -> b -> b) -> b -> [a] -> b。在您对map 感到满意之后,我会 看看这个Stack Overlow question on foldr

    模式匹配

    您可能还需要了解元组的模式匹配。 Haskell Pattern Matching.

    【讨论】:

      猜你喜欢
      • 2021-04-15
      • 2013-04-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-20
      • 1970-01-01
      • 2015-01-08
      相关资源
      最近更新 更多