List 比较成对列表中的元素

List 比较成对列表中的元素,list,haskell,tuples,List,Haskell,Tuples,我很难理解这个函数: 定义一个函数maybeA::[(String,a)]->maybeA(String,a,a),该函数接受一组对。如果输入列表有两对(a1,b1)、(a2,b2),使得a1=a2,则函数返回一个包含a1和b1,b2的元组。否则它什么也不返回。示例:maybeA[(“a”,1),(“b”,2),(“b”,3)]将返回Just(“b”,2,3) 有什么提示吗 如果您只是查找前两个匹配项,其中两对具有相同的前两个元素,则以下定义将起作用: maybeA :: [(String, a

我很难理解这个函数:

定义一个函数
maybeA::[(String,a)]->maybeA(String,a,a)
,该函数接受一组对。如果输入列表有两对
(a1,b1)、(a2,b2)
,使得a1=a2,则函数返回一个包含a1和b1,b2的元组。否则它什么也不返回。示例:
maybeA[(“a”,1),(“b”,2),(“b”,3)]
将返回
Just(“b”,2,3)


有什么提示吗

如果您只是查找前两个匹配项,其中两对具有相同的前两个元素,则以下定义将起作用:

maybeA :: [(String, a)] -> Maybe (String, a, a)
maybeA = maybeA' []
  where
    maybeA' _ []           = Nothing
    maybeA' as ((x,y):xys) = 
      case lookup x as of
        Just y' -> Just (x,y,y')
        Nothing -> maybeA' ((x,y):as) xys
请注意,如果您向它传递一个包含
(a1,b1)
(a2,b2)
(a3,b3)
的列表,其中
a1
=
a2
a2
=
a3
,它将只返回
Just(a1,b1,b2,b3)
(甚至不是同一类型)


设计一个实现这一点的函数只是一个练习:-)

如果您只是查找两对具有相同前两个元素的前两个实例,则以下定义将起作用:

maybeA :: [(String, a)] -> Maybe (String, a, a)
maybeA = maybeA' []
  where
    maybeA' _ []           = Nothing
    maybeA' as ((x,y):xys) = 
      case lookup x as of
        Just y' -> Just (x,y,y')
        Nothing -> maybeA' ((x,y):as) xys
请注意,如果您向它传递一个包含
(a1,b1)
(a2,b2)
(a3,b3)
的列表,其中
a1
=
a2
a2
=
a3
,它将只返回
Just(a1,b1,b2,b3)
(甚至不是同一类型)

设计一个实现这一点的函数作为一个练习:-)

这里有一个“组合方法”-将问题分解为小而简单的步骤,然后使用函数组合一个接一个地应用这些步骤:

import Data.List (sort, groupBy)
import Data.Maybe (listToMaybe)
import Data.Function (on)

maybeA = fmap formatAnswer . listToMaybe . dropWhile (null . drop 1) .
         groupBy ((==) `on` fst) . sort
  where
    formatAnswer ((a, b1):(_, b2):_) = (a, b1, b2)
一些注意事项:

  • fmap
    将函数应用于
    中的值(如果存在)。(
    fmap
    在许多其他类型上也以类似的方式工作。)
  • (==)
    `on
    `fst
    测试两个元组的第一个元素是否相等
  • sort
    比较元组中的两个元素,但它使用字典顺序。所以它在这里工作,但有时会改变
    b1
    b2
    的顺序。如果这对你来说是个问题, 改用
    sortBy(比较fst)
    <代码>排序
    数据.列表
    模块中,而
    比较
    数据.函数
    模块中
这里有一种“组合方法”——将问题分解为简单的小步骤,然后使用函数组合一个接一个地应用这些步骤:

import Data.List (sort, groupBy)
import Data.Maybe (listToMaybe)
import Data.Function (on)

maybeA = fmap formatAnswer . listToMaybe . dropWhile (null . drop 1) .
         groupBy ((==) `on` fst) . sort
  where
    formatAnswer ((a, b1):(_, b2):_) = (a, b1, b2)
一些注意事项:

  • fmap
    将函数应用于
    中的值(如果存在)。(
    fmap
    在许多其他类型上也以类似的方式工作。)
  • (==)
    `on
    `fst
    测试两个元组的第一个元素是否相等
  • sort
    比较元组中的两个元素,但它使用字典顺序。所以它在这里工作,但有时会改变
    b1
    b2
    的顺序。如果这对你来说是个问题, 改用
    sortBy(比较fst)
    <代码>排序
    数据.列表
    模块中,而
    比较
    数据.函数
    模块中

感谢您的帮助!你的方法应该有两个参数,这是两个列表,对吗?由于maybeA'[]=Nothing,maybeA'的类型应该是::[(String,a)]->[(String,a)]->可能(String,a,a)对吧?如果每个列表只有1对,那么这将起作用。有没有办法让这个函数只接受一个多对的列表?不过我很欣赏你的回答:)这可能是家庭作业问题所期望的,但请注意,这在实践中是一个非常糟糕的算法,因为
查找
必须对列表进行线性搜索。像
Data.Map
这样的二叉树会更好。谢谢你的帮助!你的方法应该有两个参数,这是两个列表,对吗?由于maybeA'[]=Nothing,maybeA'的类型应该是::[(String,a)]->[(String,a)]->可能(String,a,a)对吧?如果每个列表只有1对,那么这将起作用。有没有办法让这个函数只接受一个多对的列表?不过我很欣赏你的回答:)这可能是家庭作业问题所期望的,但请注意,这在实践中是一个非常糟糕的算法,因为
查找
必须对列表进行线性搜索。像
Data.Map
这样的二叉树会更好。