在下面的情况下是否可以应用eta减少?
let normalise = filter (\x -> Data.Char.isLetter x || Data.Char.isSpace x )
我期待这样的事情成为可能:
let normalise = filter (Data.Char.isLetter || Data.Char.isSpace)
......但它不是
答案 0 :(得分:10)
您的解决方案无效,因为(||)
适用于Bool
个值,而Data.Char.isLetter
和Data.Char.isSpace
属于Char -> Bool
类型。
pl为您提供:
$ pl "f x = a x || b x"
f = liftM2 (||) a b
说明:liftM2
将(||)
提升为(->) r
monad,因此它的新类型为(r -> Bool) -> (r -> Bool) -> (r -> Bool)
。
所以在你的情况下,我们会得到:
import Control.Monad
let normalise = filter (liftM2 (||) Data.Char.isLetter Data.Char.isSpace)
答案 1 :(得分:7)
import Control.Applicative
let normalise = filter ((||) <$> Data.Char.isLetter <*> Data.Char.isSpace)
答案 2 :(得分:5)
另一个值得关注的解决方案涉及箭头!
import Control.Arrow
normalize = filter $ uncurry (||) . (isLetter &&& isSpace)
&&&
有两个函数(实际上是箭头),并将结果拉到一个元组中。然后,我们暂时取消||
,以便时间变为(Bool, Bool) -> Bool
,我们就完成了所有工作!
答案 3 :(得分:2)
你可以利用Any
monoid和monoid实例来返回返回monoid值的函数:
import Data.Monoid
import Data.Char
let normalise = filter (getAny . ((Any . isLetter) `mappend` (Any . isSpace)))