2012-07-05 14 views
12

Quiero una función como la siguiente, ¿es esto posible? de hecho, no sé si existe el tipo Patrón.¿Puedo pasar un patrón a una función?

fun1 a :: Pattern a -> a -> Bool 
fun1 pattern a = case a of 
    pattern -> True 
    _ -> False 
+1

no hablo F #, pero creo que [los patrones activos] (http: // msdn.microsoft.com/en-us/library/dd233248.aspx) puede hacer algo similar. – phg

Respuesta

13

No creo que esto sea posible en Haskell.

Sin embargo, en su caso, el patrón es efectivamente una función del tipo a -> Bool. Entonces, en lugar de aceptar un patrón, acepte cualquier función desde a hasta Bool. Su ejemplo es equivalente a aplicar una función a -> Bool en un a.

Ahora, si quisiera hacer algo más general, como poder utilizar los símbolos coincidentes del patrón en el cuerpo de fun1, no podría hacerlo con una función. Sin embargo, dudo que esto sea posible con Haskell en absoluto; requeriría extrañas extensiones al sistema de tipos para tener sentido. La coincidencia de patrones en Haskell no es para nada un ciudadano de primera clase, por lo que no se pueden pasar los patrones de esa forma.

Si desea este tipo de comportamiento, consulte el libro Pattern Calculus donde el autor desarrolla y formaliza un idioma con características de coincidencia de patrones más generales que Haskell. Hace que los patrones sean ciudadanos de primera clase, a diferencia de Haskell. Todavía no he terminado este libro, pero estoy seguro de que ese código es exactamente lo que podrías escribir, entre otras cosas.

El autor creó un lenguaje en torno a sus ideas sobre la coincidencia de patrones llamada bondi; probablemente también valga la pena verificarlo, especialmente si no quieres molestarte con el libro. No sé si está listo para el uso práctico, pero ciertamente es interesante.

+0

ghc tiene esta extensión ViewPattern desde la versión 6.10 (04-Nov-2008). Con esa extensión sintáctica, esos "patrones" son solo funciones que mapean desde el valor a ser analizado hasta el resultado a ser más coincidente con el patrón. – comonad

+0

@comonad: no estoy seguro de que la extensión ViewPattern sea aplicable aquí: le permite usar funciones como patrones donde el OP quiere usar patrones como funciones. –

+0

Me refería a su segunda sección: "... como poder usar los símbolos coincidentes del patrón en el cuerpo de fun1, no podría hacerlo con una función". Bien, al usar ViewPatterns, esa función/patrón tiene que devolver los enlaces coincidentes para que la persona que llama pueda vincularlos a sus propias variables o para que el patrón los relacione más. Si eso fuera demasiado detallado (y si no recuerdo mal), existe un truco con RecordWildcards que le permite combinar variables específicas nombradas a un valor. – comonad

0

Estoy bastante seguro de que usted está buscando Ver patrones.

(ver trac/ghc/wiki o ghc/user-manual/syntax-extensions)


Cada función es un "patrón":

case "string that ends with x" of 
    (last->'x') -> True 
    _ -> False 

case "foo" of 
    (elemIndex 'g'->Just i) -> i+5 
    (elemIndex 'f'->Nothing) -> 23 
    _ -> 42 

do 
    x <- fmap foo bar 
= 
do 
    (foo->x) <- bar 
+1

Creo que estaba pidiendo lo contrario: en lugar de usar funciones como patrones, quería usar patrones como funciones. Así que quería poder invocar 'fun1 (Just x) a' y hacer coincidir el valor de' a' con el * pattern * 'Just x'.Esto es lo que la biblioteca vinculada en la respuesta aceptada le permite hacer. No obstante, no creo que ViewPatterns te permita hacer eso. –

+0

Tikhon Jelvis: Interesante, no consideró esa vista. En realidad, Jason pidió usar patrones como patrones. Pero hacer una función fuera de un patrón es trivial. AFAIC Jason es nuevo en Stackoverflow y simplemente aceptó cualquier respuesta sin comentarla; No estoy tan seguro de que quisiera una sola respuesta específica. – comonad

Cuestiones relacionadas