haskell - 将镜头传递给函数

标签 haskell haskell-lens

我想根据记录中的特定值执行排序。因此,我正在考虑将镜头传递给 lensSort 函数,但我一直无法使其工作。

理想情况下我可以做这样的事情

lensSort :: HasLens a => Lens' a b -> a -> a -> -> Ordering
lensSort lens x y | x ^. lens > y ^. lens = GT
                    | x ^. lens < y ^. lens = LT
                    | otherwise = GT

并且能够用类似的方式调用它

data Rectangle = Rectangle { _height :: Int, _width :: Int }
makeLenses'' Rectangle

let foo = [Rectangle 1 2, Rectangle 2 1]
sortBy (lensSort height) foo

我没能让它发挥作用,并且担心我可能完全找错了方向,我对 Haskell 还很陌生。

最佳答案

除了拼写错误之外,您的代码实际上几乎可以正常工作 - 唯一明显需要的是 b 实际上是可比较的。作品如下:

{-# LANGUAGE TemplateHaskell, RankNTypes #-}
import Control.Lens
import Control.Lens.TH
import Data.List

data Rectangle = Rectangle { _height :: Int, _width :: Int }
  deriving (Show)
makeLenses ''Rectangle

lensSort :: Ord b => Lens' a b -> a -> a -> Ordering
lensSort lens x y | x ^. lens > y ^. lens = GT
                    | x ^. lens < y ^. lens = LT
                    | otherwise = GT

foo :: [Rectangle]
foo = [Rectangle 1 2, Rectangle 2 1]

main = print $ sortBy (lensSort height) foo
-- [Rectangle {_height = 1, _width = 2},Rectangle {_height = 2, _width = 1}]

请注意,实际上并不需要传递实际的镜头,因为无论如何您只将其用作 setter/getter (≅函数)。所以你可以这样做

import Data.Ord (comparing)
main = print $ sortBy (comparing (^.height))

...没有任何额外的定义。

关于haskell - 将镜头传递给函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46766656/

相关文章:

haskell - 将元组转换为可折叠

haskell - 通过 ReaderT 获取带有镜头的元组子集

haskell - 变形与镜头有何关系?

list - 如何从 Haskell 中的列表中提取特定数据构造函数的术语

haskell - 从列表中删除奇数元素

Haskell:如何设置参数和返回类型的多态类型

Haskell:从Maybes 结构转换为Hashmap

长度 vs 折叠 vs 显式递归的性能特征

arrays - 如何交换项目以将一个列表转换为另一个列表

haskell - 仅当输入值为 "setter"时应用镜头 "Just x"?