Niedawno wpadłem na sytuacje, w których muszę przekazać funkcję predykatu do innej funkcji, i dość często logika, której szukam, to w zasadzie „czy ta wartość pasuje do tego wzorca?”
Dopasowywanie wzorców wydaje się być preferowane w deklaracjach, do
blokach i opisach list, ale istnieje wiele funkcji, które przyjmują predykaty a -> Bool
, w których bardzo przydatne byłoby jakoś przekazać wzorzec. Na przykład takeWhile
, until
, find
, span
, itd.
Do tej pory robiłem \a -> case a of MyCons _ -> True; otherwise -> False
lub pisałem nazwaną funkcję a la, let myPred (MyCons _) = True; myPred _ = False in
ale oba wydają się strasznie brzydkie i niezbyt idiomatyczne. „Oczywisty” (i zły) sposób byłby czymś podobnym, \(MyCons _) -> True
ale generuje to błąd, ponieważ jest stronniczy, oczywiście, i nawet wtedy wydaje się, że musi istnieć czystszy sposób.
Czy istnieje bardziej zwięzły / czysty sposób na zrobienie czegoś takiego? Czy też chodzi o rzeczy całkowicie niewłaściwe?
let myPred...
styl jest zły , ale wydaje się bardziej gadatliwy, niż oczekiwałbym bardzo prostego pomysłu, co prowadzi mnie do zastanowienia się, czy nie szczekam na niewłaściwym drzewie.
maybe :: b -> (a -> b) -> Maybe a -> b
i bool :: a -> a -> Bool -> a
, a następnie używać go z funkcji (y) jako argument (y) Boolean produkujących. np. myCons z f (MyCons x) = f x ; myCons z f _ = z
następnie zadzwoń myCons False (const True) aMyConsValue
. jest to prawie to, co napisałeś, ma tylko jeden poziom „pośredni” / „abstrakcyjny” za pomocą funkcjonalnych argumentów, wrzucony w to.
let
klauzuli, której nie lubisz - chociaż wolęwhere
klauzulę równoważną , więc nie zaśmieca to głównej definicji. Oczywiście, jeśli będziesz potrzebować tego narzędzia więcej niż jeden raz, zdefiniuj je jako funkcję najwyższego poziomu.