如何在功能编程中摆脱拳击和拆箱?

时间:2022-10-11 22:03:47

says that we want to filter out all the odd one in a list.

说我们要过滤掉列表中的所有奇数。

odd' (i,n) = odd i
unbox (i,n) = n

f :: [Int] -> [Int]
f lst = map unbox $ filter odd' $ zip [1..] lst

*Main> f [1,2,3,4]
[1,3]

it has the unpleasant boxing and unboxing.

它有令人不快的拳击和拆箱。

can we change the way we think this problem and eliminate boxing and unboxing?

我们可以改变我们认为这个问题的方式并消除拳击和拆箱吗?

@user3237465 list comprehension is indeed a good way of thinking this sort of problem. as well as function composition. well, I think we won't get rid of "wrapping the original list to [(index,value)] form and then unwrap it" without writing a special form like @Carsten König provided.

@ user3237465 list comprehension确实是思考这类问题的好方法。以及功能组成。好吧,我认为我们不会摆脱“将原始列表包装到[(索引,值)]表单然后打开它”,而不是像@CarstenKönig提供的那样写一个特殊的表单。

Or have a function that give out one value's index given the list and the value. like filter (odd . getindex) xs

或者有一个函数,给出列表和值给出一个值的索引。喜欢过滤器(odd.getindex)xs

and maybe that's why clojure made it's pattern matching strong enough to get value in complex structure.

也许这就是为什么clojure使它的模式匹配足以在复杂结构中获得价值的原因。

2 个解决方案

#1


you can always rewrite the function if you want - this comes to mind:

你可以随时重写这个功能 - 想到这个:

odds :: [a] -> [a]
odds (x:_:xs) = x : odds xs
odds [x]      = [x]
odds _        = []

aside from this both you don't need odd' and unbox:

除此之外你不需要奇怪的'和unbox:

  • odd' is just odd . fst
  • 奇怪'只是奇怪的。 FST

  • unbox is just snd
  • unbox就是这样

#2


You can write this as

你可以这样写

f xs = [x | (i, x) <- zip [0..] xs, even i]

or

f = snd . foldr (\x ~(o, e) -> (e, x : o)) ([], [])

or

import Data.Either
f = lefts . zipWith ($) (cycle [Left, Right])

#1


you can always rewrite the function if you want - this comes to mind:

你可以随时重写这个功能 - 想到这个:

odds :: [a] -> [a]
odds (x:_:xs) = x : odds xs
odds [x]      = [x]
odds _        = []

aside from this both you don't need odd' and unbox:

除此之外你不需要奇怪的'和unbox:

  • odd' is just odd . fst
  • 奇怪'只是奇怪的。 FST

  • unbox is just snd
  • unbox就是这样

#2


You can write this as

你可以这样写

f xs = [x | (i, x) <- zip [0..] xs, even i]

or

f = snd . foldr (\x ~(o, e) -> (e, x : o)) ([], [])

or

import Data.Either
f = lefts . zipWith ($) (cycle [Left, Right])