简体   繁体   English

使Haskell功能无点

[英]Making Haskell functions point-free

I'm a Haskell beginner and I've been playing around with point-free functions. 我是Haskell的初学者,我一直在玩无点功能。 I have problems with two functions - lambdabot's solutions were absolutely unreadable and made the code obfuscated, so I'm asking here in case there is a way to simplify the functions. 我有两个函数的问题 - lambdabot的解决方案是完全不可读的,并使代码混淆,所以我在这里问,以防有一种简化函数的方法。

The first function removes duplicates from a list. 第一个函数从列表中删除重复项。

func1 :: Eq a => [a] -> [a]
func1 [] = []
func1 (x:xs) = x : (func1 . filter (/=x) $ xs)

I tried making a point-free version of this function with foldr and >>= but did not succeed. 我尝试用foldr>>=这个函数的无点版本但是没有成功。

The second function maps a list to a list of tuples containing the original elements and how often they occurred in the list. 第二个函数将列表映射到包含原始元素的元组列表以及它们在列表中出现的频率。

func2 :: Eq a => [a] -> [(a, Int)]
func2 xs = map ( \f -> (f, count f xs) ) xs

where count a = length.filter(==a) . 其中count a = length.filter(==a) I am not sure if making a point-free version of this function while maintaining readability is even possible, but I'd like to make sure. 我不确定在保持可读性的同时制作这个功能的无点版本是否可行,但我想确定一下。

Any help with making the two functions point-free will be appreciated. 任何有助于使这两个功能无点的帮助将不胜感激。

Well, func1 can be written as a fold: func1 = foldr (\\x xs -> x : filter (/= x) xs) [] . 好吧, func1可以写成折叠: func1 = foldr (\\x xs -> x : filter (/= x) xs) [] 1 However, you don't have to, as it's identical to the standard function nub . 1但是,您不必这样做,因为它与标准功能nub相同。

And you can remove some points from func2 using the (&&&) :: (a -> b) -> (a -> c) -> a -> (b,c) 2 combinator from Control.Arrow : 你可以使用来自Control.Arrow(&&&) :: (a -> b) -> (a -> c) -> a -> (b,c) 2组合子从func2删除一些点:

func2 xs = map (id &&& (`count` xs)) xs

Which can then be made fully point-free: 然后可以完全无点地完成:

func2 = (id &&&) . flip count >>= map

But, frankly, I had to use lambdabot to do that last step; 但是,坦率地说,我不得不使用lambdabot做最后一步; I'd suggest keeping that function in its original form. 我建议保持该功能的原始形式。 Point-free style is only helpful when it aids comprehension; 无点风格只有在它有助于理解时才有用; if you're having difficulty making a function point-free, then it's probably counterproductive. 如果你在制作一个无点函数时遇到困难,那么它可能适得其反。

1 Which can then be made fully point-free as foldr (liftM2 (.) (:) (filter . (/=))) [] (thanks again, lambdabot!) but, again, I really don't recommend this. 1然后可以完全无点地作为foldr (liftM2 (.) (:) (filter . (/=))) [] (再次感谢,lambdabot!)但是,我再次,我真的不推荐这个。 There's not a point-free combinator for every situation. 对于每种情况没有一个无点组合器。

2 (&&&) actually has a more general type; 2 (&&&)实际上有一个更通用的类型; it works with any Arrow , rather than just (->) . 它适用于任何Arrow ,而不仅仅是(->) But that's not relevant here. 但这与此无关。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM