组合两个函数以将它们应用于相同的输入
Combining two functions to apply them to the same input
我是 Haskell 的新手,我还在摸索。我正在尝试组合两个函数(Data.Char module in base
package) as a first argument to Data.Text.filter 函数中的 isMark
和 isAlpha
。到目前为止我尝试过的是:
import qualified Data.Char as C
import qualified Data.Text as T
import Data.Text (Text)
strippedInput :: Text -> Text
strippedInput input = T.filter (C.isMark || C.isAlpha) input
哪个不起作用,或者
strippedInput input = T.filter (C.isMark . C.isAlpha) input
但显然它也不起作用,因为 C.isAlpha
的类型是 Char -> Bool
然后成为 C.isMark
的输入,它也是 Char -> Bool
类型所以类型不匹配。
我想在谓词中实现“C.isMark
OR C.isAlpha
”逻辑,但由于我的知识非常有限,我 运行 不知道如何实现搜索解决方案。
最简单的是使用 lambda 表达式:
strippedInput :: Text -> Text
strippedInput input = T.filter (<b>\x -> C.isMark x || C.isAlpha x</b>) input
您还可以利用函数是应用函子这一事实,从而使用:
import Control.Applicative(liftA2)
strippedInput :: Text -> Text
strippedInput input = T.filter (<b>liftA2 (||) C.isMark C.isAlpha</b>) input
接受的答案是完全正确的。不过,也许我想使用应用运算符;
strippedInput = T.filter $ (||) <$> C.isMark <*> C.isAlpha
但是 liftA2
的问题是,正如名称所描述的那样,它仅硬连接到两个参数函数,是的,这个问题没问题。然而... Haskell 为这项工作提供了更合理的 general 抽象。它基本上被称为函数 monad,通过添加一些实用函数和转换器功能,主要被概括为 Reader monad。但是为了简单起见,我们可以在这里尝试函数 monad。
Function/Reader monad 不仅用于链接两个而且数量不定的函数(每个函数都有两个参数),在这种情况下,第一个参数由前一个函数结果提供,第二个参数由公共读取提供只有状态(在本例中是 input
)
所以这个问题的答案也可以是
strippedInput = T.filter (C.isMark >>= (\b c -> b || C.isAlpha c) >>= return)
然而,由于 Data.Char
包中充满了 isThis
、isThat
类型的检查,我们可以展示如何扩展这种方法。
strippedInput = T.filter (C.isMark >>= (\b c -> b || C.isAlpha c)
>>= (\b c -> b || C.isSymbol c)
.
.
>>= return)
and.. 没有人阻止你做一个比较函数,比如
orWith f = \b c -> b || f c
strippedInput = T.filter $ C.isMark >>= orWith C.isAlpha
>>= orWith C.isSymbol
.
.
>>= return
我是 Haskell 的新手,我还在摸索。我正在尝试组合两个函数(Data.Char module in base
package) as a first argument to Data.Text.filter 函数中的 isMark
和 isAlpha
。到目前为止我尝试过的是:
import qualified Data.Char as C
import qualified Data.Text as T
import Data.Text (Text)
strippedInput :: Text -> Text
strippedInput input = T.filter (C.isMark || C.isAlpha) input
哪个不起作用,或者
strippedInput input = T.filter (C.isMark . C.isAlpha) input
但显然它也不起作用,因为 C.isAlpha
的类型是 Char -> Bool
然后成为 C.isMark
的输入,它也是 Char -> Bool
类型所以类型不匹配。
我想在谓词中实现“C.isMark
OR C.isAlpha
”逻辑,但由于我的知识非常有限,我 运行 不知道如何实现搜索解决方案。
最简单的是使用 lambda 表达式:
strippedInput :: Text -> Text
strippedInput input = T.filter (<b>\x -> C.isMark x || C.isAlpha x</b>) input
您还可以利用函数是应用函子这一事实,从而使用:
import Control.Applicative(liftA2)
strippedInput :: Text -> Text
strippedInput input = T.filter (<b>liftA2 (||) C.isMark C.isAlpha</b>) input
接受的答案是完全正确的。不过,也许我想使用应用运算符;
strippedInput = T.filter $ (||) <$> C.isMark <*> C.isAlpha
但是 liftA2
的问题是,正如名称所描述的那样,它仅硬连接到两个参数函数,是的,这个问题没问题。然而... Haskell 为这项工作提供了更合理的 general 抽象。它基本上被称为函数 monad,通过添加一些实用函数和转换器功能,主要被概括为 Reader monad。但是为了简单起见,我们可以在这里尝试函数 monad。
Function/Reader monad 不仅用于链接两个而且数量不定的函数(每个函数都有两个参数),在这种情况下,第一个参数由前一个函数结果提供,第二个参数由公共读取提供只有状态(在本例中是 input
)
所以这个问题的答案也可以是
strippedInput = T.filter (C.isMark >>= (\b c -> b || C.isAlpha c) >>= return)
然而,由于 Data.Char
包中充满了 isThis
、isThat
类型的检查,我们可以展示如何扩展这种方法。
strippedInput = T.filter (C.isMark >>= (\b c -> b || C.isAlpha c)
>>= (\b c -> b || C.isSymbol c)
.
.
>>= return)
and.. 没有人阻止你做一个比较函数,比如
orWith f = \b c -> b || f c
strippedInput = T.filter $ C.isMark >>= orWith C.isAlpha
>>= orWith C.isSymbol
.
.
>>= return