我尝试学习Haskell并且我不知道如何创建一个函数,该函数获取列表并将该列表中的每个元素相乘,例如。
ChildClass(speed, direction)
我尝试这样的事情,但它不起作用。如果有人知道该怎么做,对我来说真的很有帮助:
ChildClass([speed, direction])
答案 0 :(得分:6)
非常简单,你需要map
:
map product [[2,3],[8,3,2],[2,10,1],[2,2,2,2]]
product
函数乘以列表中的所有元素。它包含在Prelude中,默认导入。换句话说,它通常是可用的。
map
函数将该函数应用于列表中的每个元素。
答案 1 :(得分:4)
如果您更喜欢只有折叠的解决方案,首先要做一些经验法则:
foldl
(“lazy † left fold”),除非在非常具体的情况下(在你很长时间了解这些微妙的情况之前,你会遇到这种情况) )。foldr
(懒惰的右侧折叠)来解构列表。特别是,如果您的折叠再次生成列表,这通常是正确的选择:foldr
将仅按需消耗列表,并且它不会保留对原始头的引用,因此它甚至可以顺利地工作无限列表并避免内存爆炸(实际上,垃圾收集器可以在处理完成之前回收已经处理的列表部分!)foldl'
(严格左侧折叠)进行“原子”操作,例如计算列表中所有值的总和。所以让我们从
开始吧listOfProductInt :: [[Int]] -> [Int]
-- listOfProductInt [] = [] -- no need for that, folds already handle the empty case.
listOfProductInt lists = foldr _ [] lists
multipleInts :: (Num a) => [a] -> a
multipleInts list1 = foldl' _ 1 list1
GHC会通知你
/tmp/wtmpf-file9164.hs:4:32:
Found hole ‘_’ with type: [Int] -> [Int] -> [Int]
Relevant bindings include
lists :: [[Int]] (bound at /tmp/wtmpf-file9164.hs:4:18)
listOfProductInt :: [[Int]] -> [Int]
(bound at /tmp/wtmpf-file9164.hs:4:1)
In the first argument of ‘foldr’, namely ‘_’
不幸的是,这并不像通常那样具有信息性,因为结果和单个子列表都具有类型[Int]
。我将注释类型:
[Int] -- the sublist we're focusing on
-> [Int] -- the result of the future product-computations yet to be done
-> [Int] -- the result at this point of the computation
现在,为了首先处理议程上的子列表,我们有multipleInts
。所以,它应该看起来像
listOfProductInt lists = foldr (\l -> _ (multipleInts l)) [] lists
GHC回复
/tmp/wtmpf-file9164.hs:4:39:
Found hole ‘_’ with type: Int -> [Int] -> [Int]
Relevant bindings include
l :: [Int] (bound at /tmp/wtmpf-file9164.hs:4:34)
lists :: [[Int]] (bound at /tmp/wtmpf-file9164.hs:4:18)
listOfProductInt :: [[Int]] -> [Int]
(bound at /tmp/wtmpf-file9164.hs:4:1)
In the expression: _
In the expression: _ (multipleInts l)
In the first argument of ‘foldr’, namely
‘(\ l -> _ (multipleInts l))’
您可以将Int -> [Int] -> [Int]
或a -> [a] -> [a]
识别为合作运营商(:)
的签名,以及此处所需的内容:
listOfProductInt lists = foldr (\l -> (:) (multipleInts l)) [] lists
或者,使用无点合成,
listOfProductInt = foldr ((:) . multipleInts) []
继续执行multipleInts
:
/tmp/wtmpf-file9164.hs:7:29:
Found hole ‘_’ with type: a -> a -> a
Where: ‘a’ is a rigid type variable bound by
the type signature for multipleInts :: Num a => [a] -> a
at /tmp/wtmpf-file9164.hs:6:17
Relevant bindings include
list1 :: [a] (bound at /tmp/wtmpf-file9164.hs:7:14)
那么,a -> a -> a
a
符合Num
约束条件?这只是简单的产品操作!
multipleInts list1 = foldl' (*) 1 list1
† foldl
在值中只是懒惰,但不在脊椎中。在实践中,这往往会给你两个世界中最糟糕的事情:处理器立即被必须处理整个列表所阻塞,但它实际上并没有进行有用的计算,而只是构建了一堆内存占用懒惰的thunk。子>