haskell - 用镜头构造谓词

标签 haskell lenses

我想创建一个函数A -> Bool使用 A 的一些镜头。例如:

data A = A { _foo :: Int, _bar :: Int }
makeLenses ''A

l :: [A]

l' = filter (\a -> a^.foo > 100) l

过滤谓词看起来有点笨拙。 ((>100).(^.foo))也好不到哪里去。如果没有镜头,我会使用 ((>100) . foo) .

有没有用 lens 创建此类谓词的好方法? ?理想情况下,它还允许像 (\a -> a^.foo > 100 && a^.bar < 50) 这样的谓词。 .

最佳答案

我认为 ((>100).(^.foo))仅使用标准运算符可能是您可以做的最好的事情。如果您愿意为镜头定义新的比较运算符,您可以执行以下操作:

import Control.Lens hiding  ((.>))
import Control.Monad        (liftM2)
import Control.Monad.Reader (MonadReader)
import Data.Function        (on)

(.==) :: (MonadReader s m, Eq a) => Getting Bool s a -> a -> m Bool
(.==) l = views l . (==)
infix 4 .==

(.==.) :: (MonadReader s m, Eq a) => Getting a s a -> Getting a s a -> m Bool
(.==.) = liftM2 (==) `on` view
infix 4 .==.

(.<) :: (MonadReader s m, Ord a) => Getting Bool s a -> a -> m Bool
(.<) l = views l . flip (<)
infix 4 .<

(.<.) :: (MonadReader s m, Ord a) => Getting a s a -> Getting a s a -> m Bool
(.<.) = liftM2 (<) `on` view
infix 4 .<.

(.<=) :: (MonadReader s m, Ord a) => Getting Bool s a -> a -> m Bool
(.<=) l = views l . flip (<=)
infix 4 .<=

(.<=.) :: (MonadReader s m, Ord a) => Getting a s a -> Getting a s a -> m Bool
(.<=.) = liftM2 (<=) `on` view
infix 4 .<=.


(.>) :: (MonadReader s m, Ord a) => Getting Bool s a -> a -> m Bool
(.>) l = views l . flip (>)
infix 4 .>

(.>.) :: (MonadReader s m, Ord a) => Getting a s a -> Getting a s a -> m Bool
(.>.) = liftM2 (>) `on` view
infix 4 .>.

(.>=) :: (MonadReader s m, Ord a) => Getting Bool s a -> a -> m Bool
(.>=) l = views l . flip (>=)
infix 4 .>=

(.>=.) :: (MonadReader s m, Ord a) => Getting a s a -> Getting a s a -> m Bool
(.>=.) = liftM2 (>=) `on` view
infix 4 .>=.

(.&&.) :: Monad m => m Bool -> m Bool -> m Bool
(.&&.) = liftM2 (&&)
infix 3 .&&.

(.||.) :: Monad m => m Bool -> m Bool -> m Bool
(.||.) = liftM2 (||)
infix 3 .||.

运算符选择背后的逻辑是,点表示有镜头的一侧,因此您可以写成 foo .== 5foo .==. bar (其中 foobar 是镜头)。不幸的是,lens包还定义了自己的(.<)运算符,所以也许其他一些命名约定会更好。这只是我想到的第一个想法。

使用这些新的运算符,您将能够编写类似的东西
l' = filter (foo .> 100 .&&. bar .< 50) l

关于haskell - 用镜头构造谓词,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16519249/

相关文章:

haskell - cabal 文件中的标志

haskell - 超长方体的应用实例

haskell - 使用 Lens 过滤复合结构

haskell - 如何使用镜头库通过索引从列表中删除项目?

haskell - 依赖类约束的不明确类型变量

Java FoldMap 列表,或 "how to get around the lazy/eager dissonance"

Haskell 的 DataKinds 以及值、类型和种类的关系

scala - Monocle 的 Optionals 与部分镜片相同吗?

haskell - 使用带有镜头的一元函数修改状态

haskell - 如何在 Haskell 中使用 foldr 实现删除