从列表映射链式元素对上的函数 [英] Mapping a function on chained pairs of elements from a list

查看:106
本文介绍了从列表映射链式元素对上的函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想从链表映射一个函数链接的元素对。考虑清单:

  a = [1,2,3,4,5] 

通过使用例如函数 f a1 a2 = a1 < a2 ,我想要:

  [True,True,True,True] 

以下内容似乎适用于:

  zipWith fa(tail a)

然而,我觉得它有点的hackish。有没有更合适的方式,可能使用fold?

解决方案

我认为我可以代表Haskell社区发言,如果我告诉你认为这是在Haskell中这样做的最常用的方式。你可以使用折叠把一些东西拼凑在一起,但它显然不像第一个变体那样可读:

  fp xs = snd $ foldl (\acc x  - >(x,snd acc ++ [p(fst acc)x]))(head xs,[])(tail xs)






感谢@WillNess为上述功能提供更可读的版本,尽管它仍然没有超过 zipWith 简洁明了。

  fp = foldr g []。其中g(x:y:_)r = p x y:r; g _ _ = [] 






。在这种情况下使用折叠的问题是,通常这些元素将被单独处理,并且他们不会知道他们的邻居。他们知道的唯一值就是累加器和他们自己的值。

在这个例子中,做 f(<)[1,2,3, 4,5] 将检查一对中的左元素是否小于前一个元素,但是方式的可读性低于刚刚做的:

  fp xs = zipWith p xs(tail xs)

用法与上述相同。






请注意,我在Haskell并不专业语言,所以这种使用折叠的方法可能是以更好的方式编写的,但它永远不会超过 zipWith 方法的优雅。


I want to map a function on chained pairs of elements from a list. Consider the list:

a = [1,2,3,4,5]

By using e.g. the function f a1 a2 = a1 < a2, I want to get:

[True,True,True,True]

The following seems to work in general:

zipWith f a (tail a)

However, I find it kind of hackish. Is there a more appropriate way, maybe using fold?

解决方案

I think I can speak on behalf of the Haskell community if I tell you that that is the most idiomatic way of doing this in Haskell. You could hack something together using a fold but it is clearly not as readable as the first variant:

f p xs = snd $ foldl (\acc x -> (x, snd acc ++ [p (fst acc) x])) (head xs, []) (tail xs)


Thank you @WillNess for supplying a more readable version of above's function, although it still does not beat zipWith in brevity and clarity.

f p = foldr g [] . tails where g (x:y:_) r = p x y:r; g _ _ = []


This is really hackish. The problem with using a fold in this situation is that normally the elements will be dealt with separately and they do not "know" about their neighbours. The only values they know are the accumulator and their own.

In this example, doing f (<) [1,2,3,4,5] will check if the left element of a pair is smaller than the one before, but it is way less readable than just doing:

f p xs = zipWith p xs (tail xs)

Usage would be the same as above.


Note that I am no professional in the Haskell language, so it may be that this approach using a fold could have been written in a better way, but nevertheless it will never beat the elegance of the zipWith approach.

这篇关于从列表映射链式元素对上的函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆