如果输入是列表,我在列表理解方面遇到了一些问题。
在所有 III 练习中,不允许使用:map
,filter
和concat
!!!
要求:
一个funktion f1
获取了一个xs
三角形(a, b, cs)
列表
a
和b
的类型为Int
c
的类型为[Int]
该函数应生成一对(a · b, b + c)
的列表,对于cs中的所有c,生成列表中的c应该只显示第一个元素大于第二个元素的对 - (a · b) > b + c
。
示例:
f1 [(10,20,[1,10,100]), (4,5,[5,15,25])]
应返回以下列表:
[(200,21),(200,30),(200,120),(20,10)]
我的尝试:
f1 :: Int -> Int -> [Int] -> [(Int, Int)]
f1 a b cs = [(a*b, b+c)| c<-cs, (a*b)>(b+c)]
它工作正常,但不是列表作为输入。
所以我尝试了几种方法,但遗憾的是不是正确的方法: - (
f1 :: [(Int, Int, [Int])] -> [(Int, Int)]
第一种方法:
f1 xs = [((xs !! 0)*(xs !! 1), (xs !! 1)+c)| c<-(xs !! 2), ((xs !! 0)*(xs !! 1))>((xs !! 1)+c)]
第二种方法:
f1 let (a, b, cs) = xs = [(a*b, b+c)| c<-cs, (a*b)>(b+c)]
第3种方法:
f1 (a b cs) = [(a*b, b+c)| c<-cs, (a*b)>(b+c)]
这三个都不起作用!
dave4420解决方案:
f1 :: [(Int, Int, [Int])] -> [(Int, Int)]
f1 xs = [ (a*b, b+c) | (a, b, cs) <- xs, c <- cs, (a*b)>(b+c) ]
要求:
函数g1获取相同类型的对的列表,并从中生成简单列表。
示例:
g1 [(1,2),(3,4),(5,6)] returns [1,2,3,4,5,6]
我的尝试:
g1 :: [(Int, Int)] -> [Int]
g1 xs = [a,b | (a,b)<-xs]
我得到了一个编译错误,因为列表推导的输出中的a,b没有正确的语法。
但是我可以退回a或b或者例如A + B:
g1 xs = [a | (a,b)<-xs]
或
g1 xs = [a+b | (a,b)<-xs]
你能帮我解决这个问题吗?
再次感谢
第三部分即将来临......
答案 0 :(得分:3)
f1 :: [(Int, Int, [Int])] -> [(Int, Int)]
f1 xs = [ {-TODO-} | (a, b, cs) <- xs, c <- cs, {-TODO-} ]
我已经留下了几个{-TODO-}给你填写。
第二部分。
如果你不得不写
g1' :: [[Int]] -> [Int]
你会怎么做?您可以将g1'
修改为您想要的g1
吗?
答案 1 :(得分:1)
你已经走近了。使用
f1 :: Int -> Int -> [Int] -> [(Int, Int)]
f1 a b cs = [(a*b, b+c)| c<-cs, (a*b)>(b+c)]
首先需要重写一次以获得三倍(Int, Int, [Int])
。这是一个微不足道的变化,
f1_a :: (Int, Int, [Int]) -> [(Int, Int)]
f1_a (a,b,cs) = [(a*b, b+c) | c <- cs, a*b > b+c]
现在,您需要将该函数应用于三元组输入列表的每个元素。如果您可以使用map f1_a xs
,那将是map
,但由于您不能使用f2 :: [(Int, Int, [Int])] -> [[(Int, Int)]]
f2 xs = [f1_a x | x <- xs]
,请将其写为列表理解
concat
但是有一个级别的列表太多,你想要一个平面列表,所以你需要concat
列表列表。您也不应该使用concat
,因此您需要将其写为列表理解。
现在,concat' xss = [x | xs <- xss, x <- xs]
做了什么?
对于参数中的每个列表,对于该列表中的每个元素,将该元素放在结果中,所以
f2
现在将其应用于{{1}}。
答案 2 :(得分:1)
你有90%的路要走。
请记住,在GHCI中,您在定义之前使用let
,
但在常规源代码中,你没有。
所以,让我们看看你到目前为止所拥有的。
λ> let f1 (a,b,cs) = [(a*b, b+c)| c<-cs, (a*b)>(b+c)]
请注意,我在元组中添加了逗号。让我们找出f1
的类型。
λ> :t f1
f1 :: (Num t, Ord t) => (t, t, [t]) -> [(t, t)]
目前,您可以忽略(Num t, Ord t) =>
部分。
这是一个函数,它接受包含元素的元组,另一个元素
元素和元素列表。
所以我们无法将整个元组列表传递给它,
只有一个元组。
λ> f1 (10,20,[1,10,100])
[(200,21),(200,30),(200,120)]
λ> f1 (4,5,[5,15,25])
[(20,10)]
这是你想要的结果的第一部分。
λ> f1 (4,5,[5,15,25])
[(20,10)]
这是第二部分。 所以现在你需要另一个接受如下输入的函数:
[(10,20,[1,10,100]), (4,5,[5,15,25])]
即,我们需要一个带有元组列表的函数。
在f1
的基础上,我们可以这样写:
λ> let f2 xs = [f1 x | x <- xs]
λ> f2 [(10,20,[1,10,100]), (4,5,[5,15,25])]
[[(200,21),(200,30),(200,120)],[(20,10)]]
请注意,结果是列表列表,我们只需要一个普通列表。
由于您不允许使用concat
,请查看groovy或Daniel Fisher如何解决问题。
两种不同的方法,都很好。