ejemplos - if else haskell
Una forma más corta de escribir este código (6)
Estás buscando mfilter
en Control.Monad
:
mfilter :: MonadPlus m => (a -> Bool) -> m a -> m a
-- mfilter odd (Just 1) == Just 1
-- mfilter odd (Just 2) == Nothing
Tenga en cuenta que si la condición no depende del contenido de MonadPlus
, puede escribir en su lugar:
"foo" <$ guard (odd 3) -- Just "foo"
"foo" <$ guard (odd 4) -- Nothing
El siguiente patrón aparece con mucha frecuencia en el código de Haskell. ¿Hay una forma más corta de escribirlo?
if pred x
then Just x
else Nothing
Hm ... Está buscando un combinador que toma una a
, una función a -> Bool
y devuelve una Maybe a
. ¡Detener! Hora de hoogle No hay una coincidencia completa, pero el find
está bastante cerca:
find :: (a -> Bool) -> [a] -> Maybe a
Dudo que puedas encontrar tu función en alguna parte. Pero ¿por qué no definirlo por ti mismo?
ifMaybe :: (a -> Bool) -> a -> Maybe a
ifMaybe f a | f a = Just a
ifMaybe _ _ = Nothing
Por lo general, soy un gran fanático de los códigos muy genéricos, pero en realidad encuentro que esta función exacta es lo suficientemente útil a menudo, especializada en Maybe
, que la mantengo en lugar de usar guard
, mfilter
y similares.
El nombre que uso para eso es justIf
, y normalmente lo uso para hacer cosas como esta:
∀x. x ⊢ import Data.List
∀x. x ⊢ unfoldr (justIf (not . null . snd) . splitAt 3) [1..11]
[[1,2,3],[4,5,6],[7,8,9]]
Básicamente, cosas en las que se debe realizar algún tipo de filtrado o comprobación de elementos en una expresión compuesta, por lo que Maybe
se utiliza para indicar el resultado del predicado.
Para la versión especializada como esta, realmente no hay mucho que puedas hacer para acortarla. Ya es bastante simple. Hay una línea muy fina entre ser conciso, y simplemente jugar golf en tu código para el conteo de personajes, y para algo así de simple, no me preocuparía realmente tratar de "mejorarlo" ...
Puedes usar guard
para lograr este comportamiento:
guard (pred x) >> return x
Este es un comportamiento tan útil en general que incluso he definido para ensure
en mi propio conjunto de códigos de una sola vez (todo el mundo tiene una cosa así, ¿verdad? ;-):
ensure p x = guard (p x) >> return x
Utilizar:
(?:) (5>2) (Just 5,Nothing)
de Data.Bool.HT.
f pred x = if pred x then Just x else Nothing
Dada la definición anterior, simplemente puede escribir:
f pred x
Por supuesto, esto no es diferente al de Daniel Wagner o FUZxxl, ifMaybe
es ifMaybe
. Pero su nombre es simplemente f
, lo que lo convierte en el más corto, y su definición es precisamente el código que proporcionó, lo que lo convierte en el más correcto y fácilmente comprobado. ;)
Algunos ghci, solo por diversión
ghci> let f pred x = if pred x then Just x else Nothing
ghci> f (5>) 2
Just 2
ghci> f (5>) 6
Nothing
Si no pudiste decirlo, esta no es una respuesta muy seria. Los otros son un poco más perspicaces, pero no pude resistir la respuesta irónica para "hacer este código más corto".