按嵌套字段过滤

时间:2020-03-15 17:31:12

标签: haskell

“我的汽车”类型的子类型为“零件”:

data Part =
  Part
    { currency :: Text
    , value    :: Float
    }
  deriving (Generic, Show)

data Car =
  Car
    { brand       :: Text
    , engine      :: Part
    }
  deriving (Generic, Show)

我正在尝试访问和拟合这样的汽车列表:

filterByEnginePrice :: [Car] -> Float -> [Car]
filterByEnginePrice cars threshold =
  Prelude.filter (\car -> engine car <= threshold) cars

但是,GHC给我以下错误:

 • Couldn't match expected type ‘Part’ with actual type ‘Float’

这很有意义,因为我想按value而不是Part进行过滤。访问过滤器功能中的value字段的语法是什么?

1 个答案:

答案 0 :(得分:5)

您可以使用value :: Part -> Float getter来获取值:

filterByEnginePrice :: [Car] -> Float -> [Car]
filterByEnginePrice cars threshold = Prelude.filter (\car -> value (engine car) <= threshold) cars

但是在lambda表达式的头部“解包”数据构造函数更为习惯:

filterByEnginePrice :: [Car] -> Float -> [Car]
filterByEnginePrice cars threshold = Prelude.filter (\Car { engine=Part {value=v} } -> v <= threshold) cars

或者我们可以使用@oisdk指定的无点表达式:

filterByEnginePrice :: [Car] -> Float -> [Car]
filterByEnginePrice cars threshold = Prelude.filter ((threshold >=) . value . engine) cars