Недавно я сталкивался с ситуациями, когда мне нужно передать функцию-предикат в другую функцию, и довольно часто логика, которую я ищу, по сути, «соответствует ли это значение этому шаблону?»
Сопоставление с образцом, по-видимому, предпочтительнее в объявлениях, блоках do
и включении списков, но есть ряд функций, которые принимают предикат a -> Bool
, где было бы очень удобно каким-то образом передать образец. Например, takeWhile
, until
, find
, span
и т. д.
До сих пор я делал \a -> case a of MyCons _ -> True; otherwise -> False
или писал именованную функцию а-ля let myPred (MyCons _) = True; myPred _ = False in
, но оба они кажутся ужасно уродливыми и не очень идиоматичными. «Очевидным» (и неправильным) способом будет что-то вроде \(MyCons _) -> True
, но это, естественно, выдает ошибку из-за частичности, и даже тогда кажется, что должен быть более чистый способ.
Есть ли более краткий/чистый способ сделать что-то подобное? Или я поступаю совершенно неправильно?
let
, которое вам не нравится, хотя я предпочитаю эквивалентное предложениеwhere
, чтобы оно не загромождало основное определение. Конечно, если вам понадобится эта утилита более одного раза, вы должны определить ее как функцию верхнего уровня. - person Robin Zigmond   schedule 08.01.2020let myPred...
плохим, но он кажется гораздо более многословным, чем я ожидал, для очень простой идеи, что заставляет меня задуматься, не ошибаюсь ли я . - person David Sampson   schedule 08.01.2020maybe :: b -> (a -> b) -> Maybe a -> b
иbool :: a -> a -> Bool -> a
, а затем использовать ее с функциями, производящими логические значения, в качестве аргумента (ов). напримерmyCons z f (MyCons x) = f x ; myCons z f _ = z
, затем позвонитеmyCons False (const True) aMyConsValue
. это почти то, что вы написали, просто есть еще один уровень косвенности/абстракции через функциональные аргументы, встроенные в него. - person Will Ness   schedule 09.01.2020