Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Making Haskell functions point-free

I'm a Haskell beginner and I've been playing around with point-free functions. 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.

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.

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). 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.

like image 744
sps Avatar asked Dec 03 '22 04:12

sps


1 Answers

Well, func1 can be written as a fold: func1 = foldr (\x xs -> x : filter (/= x) xs) [].1 However, you don't have to, as it's identical to the standard function nub.

And you can remove some points from func2 using the (&&&) :: (a -> b) -> (a -> c) -> a -> (b,c)2 combinator from Control.Arrow:

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; 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. There's not a point-free combinator for every situation.

2(&&&) actually has a more general type; it works with any Arrow, rather than just (->). But that's not relevant here.

like image 86
ehird Avatar answered Dec 28 '22 00:12

ehird