本文介绍了在Haskell中为布尔函数执行`和`和`or`的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述 我只写了以下两个函数: fand ::(a - > Bool) - > (a - > Bool) - > a - > Bool fand f1 f2 x =(f1 x)&& (f2 x) f_or ::(a - > Bool) - > (a - > Bool) - > a - > Bool f_or f1 f2 x =(f1 x)|| (f2 x) 它们可以用来组合两个布尔函数的值,例如: p> import Text.ParserCombinators.Parsec import Data.Char nameChar = satisfy(isLetter` f_or` isDigit) 看过这两个函数后,我意识到它们非常有用。以至于我现在怀疑它们被包含在标准库中,或者更可能有一种干净的方式来使用现有函数来执行此操作。 什么是这样做的正确方式? 解决方案 pre> f_and = liftM2(&&) f_or = liftM2(||) 或 = liftA2(&&) = liftA2( (( - >)r)中的 $ / code> code> applicationative functor。 应用版本 b 为什么?我们有: pre $ code>实例应用(( - >)a)其中(*>)fgx = fx(gx) liftA2 fab = f< $> a * b $ b $($>)= fmap 实例Functor(( - >)r)其中 fmap =(。) 所以: \fg - > liftA2(&& amp; f)f g = \ f g - > (&& amp;)< $> f * g - 定义liftA2 = \f g - > ((& amp;& amp;)) g - 定义< $> = \ f g x - > (((&))。f)x)(g x) - defn of * - (。)f g = \ x - > f(g x) = \ f g x - > ((&))(f x))(g x) - ()的定义 = \ f g x - > (f x)&& (gx) - infix(&&& amp;& amp; amp;& amp; amp;&&&&&&&&& ;;); ,我们有: Monad版本 instance Monad(( - >)r)其中 return = const f>> = k = \\ \\ r - > k(fr)r so: \fg - > liftM2(&& amp; f)f g = \ f g - > do {x1< -f; x2 gt;> = \ x2 - > return > =) = \fg - > (\ r - >(\ x1 - > g>> = \ x2 - > const((& $ b = \fg - > (\ r - >(\ x1 - > (\r→>(\ x2 - > const((& (fr)r) - defn of(>> =) = \ fgx - > (& amp;& amp;& amp;& amp;& amp;& amp;& amp;& amp;& amp;&& ((ξ)(f x)x2))(g x)x - beta减少 = \\ ff x - > const((&))(f x)(g x))x - beta reduce = \ f g x - > ((&))(f x)(g x)) - defn of const = \ f g x - > (f x)&& (g x) - inline(&& amp;& amp;& amp;& amp;& amp;& amp; amp;& amp;&)& b)< / code>I just wrote the following two functions:fand :: (a -> Bool) -> (a -> Bool) -> a -> Boolfand f1 f2 x = (f1 x) && (f2 x)f_or :: (a -> Bool) -> (a -> Bool) -> a -> Boolf_or f1 f2 x = (f1 x) || (f2 x)They might be used to combined the values of two boolean functions such as:import Text.ParserCombinators.Parsecimport Data.CharnameChar = satisfy (isLetter `f_or` isDigit)After looking at these two functions, I came to the realization that they are very useful. so much so that I now suspect that they are either included in the standard library, or more likely that there is a clean way to do this using existing functions.What was the "right" way to do this? 解决方案 One simplification,f_and = liftM2 (&&)f_or = liftM2 (||)or = liftA2 (&&) = liftA2 (||)in the ((->) r) applicative functor.Applicative versionWhy? We have:instance Applicative ((->) a) where (<*>) f g x = f x (g x)liftA2 f a b = f <$> a <*> b(<$>) = fmapinstance Functor ((->) r) where fmap = (.)So: \f g -> liftA2 (&&) f g= \f g -> (&&) <$> f <*> g -- defn of liftA2= \f g -> ((&&) . f) <*> g -- defn of <$>= \f g x -> (((&&) . f) x) (g x) -- defn of <*> - (.) f g = \x -> f (g x)= \f g x -> ((&&) (f x)) (g x) -- defn of (.)= \f g x -> (f x) && (g x) -- infix (&&)Monad versionOr for liftM2, we have:instance Monad ((->) r) where return = const f >>= k = \ r -> k (f r) rso: \f g -> liftM2 (&&) f g= \f g -> do { x1 <- f; x2 <- g; return ((&&) x1 x2) } -- defn of liftM2= \f g -> f >>= \x1 -> g >>= \x2 -> return ((&&) x1 x2) -- by do notation= \f g -> (\r -> (\x1 -> g >>= \x2 -> return ((&&) x1 x2)) (f r) r) -- defn of (>>=)= \f g -> (\r -> (\x1 -> g >>= \x2 -> const ((&&) x1 x2)) (f r) r) -- defn of return= \f g -> (\r -> (\x1 -> (\r -> (\x2 -> const ((&&) x1 x2)) (g r) r)) (f r) r) -- defn of (>>=)= \f g x -> (\r -> (\x2 -> const ((&&) (f x) x2)) (g r) r) x -- beta reduce= \f g x -> (\x2 -> const ((&&) (f x) x2)) (g x) x -- beta reduce= \f g x -> const ((&&) (f x) (g x)) x -- beta reduce= \f g x -> ((&&) (f x) (g x)) -- defn of const= \f g x -> (f x) && (g x) -- inline (&&) 这篇关于在Haskell中为布尔函数执行`和`和`or`的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!
10-31 22:04