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, doblokach 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 -> Falselub pisałem nazwaną funkcję a la, let myPred (MyCons _) = True; myPred _ = False inale oba wydają się strasznie brzydkie i niezbyt idiomatyczne. „Oczywisty” (i zły) sposób byłby czymś podobnym, \(MyCons _) -> Trueale 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 -> bi 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 _ = znastę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.
letklauzuli, której nie lubisz - chociaż wolęwhereklauzulę 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.