使Haskell功能无点

sps*_*sps 4 haskell pointfree

我是Haskell初学者,我一直在玩无点功能.我有两个函数的问题 - lambdabot的解决方案是完全不可读的,并使代码混淆,所以我在这里问,以防有一种简化函数的方法.

第一个函数从列表中删除重复项.

func1 :: Eq a => [a] -> [a]
func1 [] = []
func1 (x:xs) = x : (func1 . filter (/=x) $ xs)
Run Code Online (Sandbox Code Playgroud)

我试图使这一功能的免费点版本foldr>>=,但没有成功.

第二个函数将列表映射到包含原始元素的元组列表以及它们在列表中出现的频率.

func2 :: Eq a => [a] -> [(a, Int)]
func2 xs = map ( \f -> (f, count f xs) ) xs
Run Code Online (Sandbox Code Playgroud)

哪里count a = length.filter(==a).我不确定在保持可读性的同时制作这个功能的无点版本是否可行,但我想确定一下.

任何有助于使这两个功能无点的帮助将不胜感激.

ehi*_*ird 17

好吧,func1可以写成折页:func1 = foldr (\x xs -> x : filter (/= x) xs) [].1但是,您不必这样做,因为它与标准功能相同nub.

你可以从func2使用(&&&) :: (a -> b) -> (a -> c) -> a -> (b,c)2组合器中删除一些点Control.Arrow:

func2 xs = map (id &&& (`count` xs)) xs
Run Code Online (Sandbox Code Playgroud)

然后可以完全无点地完成:

func2 = (id &&&) . flip count >>= map
Run Code Online (Sandbox Code Playgroud)

但是,坦率地说,我不得不使用lambdabot做最后一步; 我建议保持该功能的原始形式.无点风格只有在它有助于理解时才有用; 如果你在制作一个无点函数时遇到困难,那么它可能适得其反.

1然后可以完全没有点foldr (liftM2 (.) (:) (filter . (/=))) [](再次感谢lambdabot!)但是,我真的不推荐这个.对于每种情况没有一个无点组合器.

2 (&&&)实际上有一个更通用的类型; 它适用于任何Arrow,而不仅仅是(->).但这与此无关.