2011-12-14 13 views
8

Podemos usar sinónimo de tipo para definiciones de funciones, p. Ej.Ejemplo de definición de función en el constructor de datos de un nuevo tipo

type FuncDef = Int -> Int -> Int 

Esto nos evita escribir una definición de función larga cada vez.

Uso:

someFunc :: FuncDef -> Int 

En lugar de

someFunc :: (Int -> Int -> Int) -> Int 

que es más fácil de leer y menos código.

Los tipos de datos algebraicos simples son simples y directos, etc.

data AType = X | Y | Z Int 
matchType :: AType -> Bool 
matchType X = .. 
matchType Y = .. 
matchType (Z _) = .. 

Al mirar más en tipos de datos de Haskell, descubrí que podemos tener en la definición de la función constructor de datos en la definición de nuevo tipo.

data MyType a b = X | Y (a -> b) 

Esto me desconcierta un poco y no he visto muchos ejemplos de esto. En cierto modo, la idea de función de orden superior en la que una función puede tomar otra función como argumento es similar a esta situación, excepto que aquí se aplica al tipo de datos. La wiki de Haskell no dice mucho sobre "definición de tipos de datos de alto orden". Me doy cuenta de que puedo estar equivocando todos estos términos, así que por favor corrígeme, y apúntame a leer más. Realmente quiero ver un uso concreto de esto. ¡Gracias!

matchMyType :: (MyType a b) -> Bool 
matchMyType X = .. 
matchMyType Y ?? = .. 
+8

Creo que es posible que te preocupes demasiado! Como dices, las funciones se pueden pasar como argumentos. Eso es porque las funciones no son intrínsecamente diferentes de cualquier otro valor. Puede ponerlos en un tipo de datos y extraerlos por coincidencia de patrones. Eso es todo lo que hay que hacer. –

+0

gracias +1, tiene sentido lo que dijiste. ¿Me puede dar un ejemplo en el que me gustaría poner una función en una estructura de datos en lugar de simplemente valores, p. enteros en un árbol? – vis

+1

Bueno, la mayoría de los usos prácticos que puedo pensar para los tipos de datos que contienen funciones son más complicados y probablemente solo lo distraigan del problema. Si desea un ejemplo genérico, la respuesta de dave4420 le irá bien. Si quiere algo más difícil de considerar, el ejemplo obligatorio es probablemente el [transformador de mónada de estado] (http://hackage.haskell.org/packages/archive/transformers/latest/doc/html/Control-Monad-Trans-State -Lazy.html # g: 2). –

Respuesta

11

Puede usar este tipo de patrón en muchas situaciones. Por ejemplo, si desea una función que transforma las cadenas de diversas maneras, es posible que tenga un tipo de datos como esto (Esto es sólo un ejemplo que demuestra el principio - no escribir código como este!):

data StringTransformation = 
    -- | Doesn't transform the string at all 
    NoTransformation | 
    -- | Takes the string and generates a suffix that should be appended 
    Append (String -> String) | 
    -- | Takes the string and generates a prefix that should be prepended 
    Prepend (String -> String) | 
    -- | Takes the string and transforms it arbitrarily to a new string 
    Map (String -> String) 

Entonces, un programa que utiliza esto podría verse así:

-- | Returns 'True' if the name is male 
isMaleName :: String -> Bool 
isMaleName = ... 

-- | Adds a title to a name, for example "John Smith" -> "Mr. John Smith" 
addTitle :: StringTransformation 
addTitle = 
    PrependTransformation $ \ name -> 
    if isMaleName name 
    then "Mr. " 
    else "Mrs. " 

-- Applies a string transformation to a 'String'. 
transformString :: StringTransformation -> String -> String 
transformString NoTransformation str = str 
transformString (Append f) str  = str ++ f str 
transformString (Prepend f) str  = f str ++ str 
transformString (Map f) str   = f str 
+0

+1 buen ejemplo :) aceptaré la respuesta si no obtengo ninguna otra. – vis

4
data Thingy a b = A b 
       | B (a -> b) 

really :: Thingy a b -> a -> b 
really (A x) _ = x    -- x :: b 
really (B f) y = f y   -- f :: a -> b, y :: a, f y :: b 

Como dice C.A.McCann, no hay nada especial acerca de las funciones de verdad.

+0

gracias. creo que el orden de los argumentos en la coincidencia de patrones no es correcto. sí veo cómo hacer coincidencia de patrones en la función en el tipo de datos, similar a cualquier función normal de orden alto. ¿por qué almacenar una función en el tipo? : s – vis

Cuestiones relacionadas