2010-07-30 3 views
15

tengo una función que tiene un tipo de retorno de Maybe ([(Int,Int)],(Int,Int))Operando en un regreso de un Quizá que contiene "sólo"

quisiera llamar a esto de otra función y realizar una operación sobre los datos.

Sin embargo, el valor de retorno está contenido en Just. El segundo método toma ([(Int,Int)],(Int,Int)) y por lo tanto no aceptará Just ([(Int,Int)],(Int,Int)).

¿Hay alguna manera de recortar el Just antes de aplicar el segundo método?

No entiendo completamente el uso de Just dentro de Maybe - sin embargo, me han dicho que el tipo de devolución para el primer Método debe ser Maybe.

+0

Tal vez se utiliza si su seguro del tipo del valor de retorno. Por ejemplo, su método podría devolver una cadena de error. –

+7

@Jonathan Fischoff: Tal vez * no * se usa si no está seguro del tipo. No hay forma de que un método devuelva 'Maybe ([(Int, Int)], (Int, Int))' podría devolver una cadena de error. Tal vez se usa cuando no sabes si vas a tener un valor para devolver o no, así que puedes devolver el valor Justo o Nada. – Chuck

+0

@Jonathan Fischoff: En parte correcto. Utiliza Maybe cuando no puede haber ningún resultado (Nothing), por ejemplo 'getPosition :: List a -> Maybe Integer'. Utiliza 'O' para devolver (sin juego de palabras) un valor de retorno válido (Derecha) o un error (Izquierda). Editar: @Chuck fue más rápido. – delnan

Respuesta

6

Está buscando fromJust. ¡Pero solamente si usted es cierto su función Maybe no va a devolver un Nothing!

+0

Gracias, eso lo hará. Siempre devuelve un valor cuando se llama desde este método porque solo estoy reciclando un método escrito para otra cosa. – KeepItFoolish

+11

de Just se considera mala forma en Haskell, al igual que cualquier función parcial como 'head'. Yo recomendaría cualquiera de las alternativas en la respuesta de TomMD. – luqui

46

Existen varias soluciones a su problema, todas basadas en la coincidencia de patrones. Estoy suponiendo que tiene dos algoritmos (ya que no dio el nombre de ellos, lo haré):

algorithm1 :: a -> Maybe b 
algorithm2 :: b -> c 
input :: a 

1) Pattern matching se realiza normalmente desde una declaración de caso (continuación) o una función.

let val = algorithm1 input 
in case val of 
    Nothing -> defaultValue 
    Just x -> algorithm2 x 

Todas las demás soluciones presentadas utilizan la coincidencia de patrones, solo presento las funciones estándar que realizan la coincidencia de patrones por usted.

2) El preludio (y Data.Maybe) tienen algunas funciones incorporadas para ocuparse de Maybe s. La función maybe es excelente, le sugiero que la use. Se define en las bibliotecas estándar como:

maybe :: c -> (b -> c) -> Maybe b -> c 
maybe n _ Nothing = n 
maybe _ f (Just x) = f x 

Su código se vería así:

maybe defaultValue algorithm2 (algorithm1 input) 

3) Desde Tal vez es una functor podría utilizar fmap. Esto tiene más sentido si no tiene un valor predeterminado. La definición:

instance Functor Maybe where 
    fmap _ Nothing  = Nothing 
    fmap f (Just a)  = Just (f a) 

lo que el código se vería así:

fmap algorithm2 (algorithm1 input) 

Esta salida será un valor Maybe (Nothing si el resultado de algorithm1 es Nothing).

4) Por último, y muy desaconsejado, es fromJust. Solo úsela si está seguro de que el primer algoritmo devolverá Just x (y no Nothing). ¡Ten cuidado! Si llama al fromJust val cuando val = Nothing, obtiene una excepción, que no es apreciada en Haskell.Su definición:

fromJust   :: Maybe b -> b 
fromJust Nothing = error "Maybe.fromJust: Nothing" -- yuck 
fromJust (Just x) = x 

Dejando su código para que parezca:

algorithm2 (fromJust (algorithm1 input)) 
+3

Lo pondría al revés: la coincidencia de patrones es la manera canónica de lidiar con un resultado 'Quizás', los demás son solo abreviaturas de formas comunes de hacerlo. (Dado que el OP probablemente no los conozca, también mencionaría sus definiciones.) –

+0

Buen punto. En retrospectiva, creo que comencé con 'fromJust' simplemente porque esa era la respuesta ya dada y aceptada informalmente por el autor de la pregunta. –

+0

A pesar de 'yuck', me parece que es la forma más fácil de entender esto. Gracias por su respuesta en cualquier caso. – vikingsteve

Cuestiones relacionadas