有一种简单的方法。要取一个数字列表,比如说123456.然后将奇数放三乘,偶数乘以1.
即。 (1 * 3)+(2 * 1)+(3 * 3)+(4 * 1)+(5 * 3)+(6 * 1)
我在想某个地方的地图功能。但我不知道如何将* 3映射到奇数放置的值。哦,如果你可以给我一个不是前奏的版本,就像实际的函数或函数一样好,就好像它是从外部haskell文件中导入的那样
感谢您的帮助
答案 0 :(得分:14)
好的,正如我之前在评论中写的那样,zipWith (*) (cycle [3,1]) xs
正是您所寻找的。但首先,一个小的挑剔:列表的头部我会称之为第0个元素,这就是为什么我将1和3转换为: - )
我们来看一个简单的例子;让xs
成为[9,8,7,3,2]
。 cycle [3,1]
只是一遍又一遍地重复它的论证,这将是一个以[3,1,3,1,3,1,...]开头的无限列表。 zipWith f xs ys
做的是xs
的head元素和ys
的head元素,并将f
(应该是两个参数的函数)应用于这些元素 - f
的结果会转到zipWith
结果的前面。如果x或y中的一个变空,我们就完成了;否则我们继续前进。
结果的第一个元素是(3 * 9)
,然后是(1 * 8)
,(3 * 7)
,(1 * 3)
,(3 * 2)
,我们就完成了!
您可以查看zipWith
here的定义。
如果你确实不想使用预定义的函数,你可以定义一个'交替地图',取两个函数而不是一个,将第一个函数应用到参数列表的头部并在递归调用上切换函数。我会让你弄清楚那里的细节......
答案 1 :(得分:2)
这个怎么样,假设xs
是您的数字列表:
map (uncurry ($)) (zip (cycle [((*) 1), ((*) 3)]) xs)
以下是其工作原理:
[((*) 1), ((*) 3)]
是包含两个函数的列表。第一个乘以一个数字;第二个将数字乘以三。
cycle [...]
创建这两个函数的无限列表,一个接一个地重复,[×1,×3,×1,×3 ......]
zip (cycle [...]) xs
获取您的数字并将其与功能配对。所以如果xs
是[1..6]那么你得到[(×1,1),(×3,2),(×1,3),(×3,4),(×1, 5),(×3,6)]。
$ :: (a -> b) -> a -> b
函数是组合子;它需要一个函数a→b并将其应用于一个值。因此map (uncurry ($)) (zip ...)
获取(函数,数字)对的列表并将该函数应用于该数字。您需要uncurry
,因为列表包含对,因此要映射的函数的签名必须为((a -> b), a) -> b
。
这会留下结果列表;在这种情况下[1,6,3,12,5,18]。
答案 2 :(得分:1)
我的第一个想法是使用累积贴图,使用累积参数来标记它是在'偶数'还是'奇数'循环。我看到没有其他人这样做过,所以让我们看看它是怎么回事......
import Data.List (mapAccumL)
yourFunc = snd . mapAccumL mult True -- 'True' represents an odd index, starting from 1
where
mult True x = (False, 3 * x)
mult False x = (True , x)
答案 3 :(得分:0)
您仍然可以使用地图,只需先使用zip:
let list' = zip [1..] list
in map (\(cnt,val) -> if odd cnt then val * 3 else val) list'
上面你可以看到如何使结果依赖于索引以及该索引处的值。这是一个相当普遍的解决方案,通过替换lambda(map
的第一个参数),您可以创建许多变体。使用cycle
和zipWith
的更专业的解决方案更短,并且对于Haskell中的人来说非常易读。
在声明不作业之后编辑并充实。
答案 4 :(得分:0)
如果你想做这种无点风格,没有比使用cycle
和某种形式的zip
更好的方法了。 (无点意味着,“没有命名let-bound或lambda-bound变量。”)我有两个问题:
cycle
和其他鲜为人知的列表函数(必须有一百个列表函数)有多熟悉?问题越普遍,读者越熟悉,我就越有可能推荐无点风格。对于针对不太熟悉Haskell的读者的一次性解决方案,我可能会尝试递归函数:
mult31 [] = 0
mult31 [x:x':xs] = x * 3 + x' * 1 + mult31 xs
mult31 [x] = x * 3
或者如果你想变得聪明,你可以使用一对交替功能:
mult31 = m3
where m3 (x:xs) = x * 3 + m1 xs
m3 [] = 0
m1 (x:xs) = x * 1 + m3 xs
m1 [] = 0
对于Haskell老手来说,这些函数中的任何一个对于cycle
使用zip函数的东西来说都不太自然,但对于刚开始的人来说,它们可能更容易理解。