List Haskell-if-else返回干净的元组

List Haskell-if-else返回干净的元组,list,haskell,tuples,List,Haskell,Tuples,我的家庭作业是,如果第一个元组的第二个元素与第二个元组的第一个元素相同,则将两个元组分组到一个列表中。然后,如果第一个元组是(a,b),第二个元组是(b,c),则必须将元组(a,c)添加到结果列表中 我编写了第一个函数,其中包含一个元组的元素,第二个包含多个元组的列表,并对每个元组进行比较 这一个工作正常: c1 = ("a","x") d1 = [ ("x","b"), ("z","c"), ("x","b"), ("z","c") , ("x","b"), ("z","c"), (

我的家庭作业是,如果第一个元组的第二个元素与第二个元组的第一个元素相同,则将两个元组分组到一个列表中。然后,如果第一个元组是
(a,b)
,第二个元组是
(b,c)
,则必须将元组
(a,c)
添加到结果列表中

我编写了第一个函数,其中包含一个元组的元素,第二个包含多个元组的列表,并对每个元组进行比较

这一个工作正常:

c1 = ("a","x")
d1 = [ ("x","b"), ("z","c"), ("x","b"), ("z","c")
     , ("x","b"), ("z","c"), ("x","b"), ("z","c") ]

getByOne c1 a1 = filter (/=[])
  [ if (fst  (last(take n a1))) == (snd c1)
    then [((fst c1),  (snd  (last(take n a1))))]
    else  [] | n <- [1..(length a1) ] ]
但问题是,我不能把if-then和else语句仅仅放在简单的元组中,所以我创建了一个新的列表。在这个“解决方法”的最后,我得到了列表中的列表,等等。而且,若输出列表更大,那个么列表中会有更多的列表


有没有办法只传递元组或空元组,或者我应该以某种方式对这些列表进行分组?

您可以使用

concat :: [[a]] -> [a]
然后你甚至不需要
过滤(/=[])
——顺便说一句,条件
(/=[])
写得更习惯
而不是。null
,因为
null
测试没有对其参数施加
Eq
约束(这里已经有了约束,所以这只是一个习惯用法问题)

此外,
last(取n a1)
只是
a1
n
第四个元素,如果
1
  • [1..(长度a1)]
    可以编写
    [1..长度a1]
  • 更好的方法是,使用防护装置并清除if-then-else:

    getByOne (a, b) a1 = [ (a, d) | (c, d) <- a1
                                  , b == c ]
    
    简化为

    getByOne (a, b) = map (\(_, c) -> (a, c))
                         . filter (\(c, _) -> b == c)
    

    但这不是你想要的输出,对吗?你想要什么样的输出,我不清楚。好吧,只要这是我家庭作业的一部分,我会试着自己解决这个任务。再次感谢您的帮助。+1看到这样的内容提醒我Haskell代码的可读性。结果函数比口头描述更清晰、更简短。concat::[[a]->[a]在这种情况下非常有用。
    concat
    下的
    []
    条目对于表示消除(过滤)非常惯用,和
    如果else
    可以进一步替换为另一个理解,在你的
    #3
    中:
    [[(fst c1,y)| snd c1==x]|(x,y)
    
    getByOne c1 a1 = concat $ map (something c1) a1
    
    getByOne c1 a1 = concat [something c1 x | x <- a1]
    
    getByOne (f,s) a1 = concat [ if a == s then [(f,b)] else [] | (a,b) <- a1]
    
    getByOne (f,s) list = [(f,b) | (a,b) <- list, a == s]
    
    [ if (fst  (last(take n a1))) == (snd c1)
      then [((fst c1),  (snd  (last(take n a1))))]
      else  [] | n <- [1..(length a1) ] ]
    
    [ if fst lastElement == snd c1
      then [(fst c1, snd lastElement)]
      else [] | n <- [1 .. length a1 ]
              , let lastElement = last (take n a1) ]
    
    [ if x == snd c1
      then [(fst c1, y)]
      else [] | (x, y) <- a1 ]
    
    import Data.Maybe
    
    c1 = ("a","x")
    d1 = [ ("x","b"), ("z","c"), ("x","b"), ("z","c")
         , ("x","b"), ("z","c"), ("x","b"), ("z","c") ]
    
    getByOne c1 a1 = catMaybes
            [ if x == snd c1
              then Just (fst c1, y)
              else Nothing | (x, y) <- a1 ]
    
    getByOne (a, b) a1 = [ (a, d) | (c, d) <- a1
                                  , b == c ]
    
    getByOne (a, b) a1 = map (\(_, c) -> (a, c))
                         . filter (\(c, _) -> b == c)
                         $ a1
    
    getByOne (a, b) = map (\(_, c) -> (a, c))
                         . filter (\(c, _) -> b == c)