η减少可能吗?

时间:2014-05-07 13:07:10

标签: haskell pointfree

在下面的情况下是否可以应用eta减少?

let normalise = filter (\x -> Data.Char.isLetter x || Data.Char.isSpace x )

我期待这样的事情成为可能:

let normalise = filter (Data.Char.isLetter || Data.Char.isSpace)

......但它不是

4 个答案:

答案 0 :(得分:10)

您的解决方案无效,因为(||)适用于Bool个值,而Data.Char.isLetterData.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)))