utilizan uso texto paréntesis parentesis los guion funcion ejemplos dentro cuando corchetes con como haskell parentheses

haskell - uso - ¿Qué usan los paréntesis() en su propia media?



uso de parentesis y corchetes (4)

Leí en aprender que haskell eso

Los miembros de la enumeración son tipos ordenados secuencialmente ... Tipos en esta clase: () , Bool, Char ...

También aparece en algunas firmas:

putChar :: Char -> IO ()

Es muy difícil encontrar información al respecto en Google ya que las respuestas se refieren a los problemas de los "paréntesis comunes" (uso en llamadas a funciones, problemas de precedencia y similares).

Por lo tanto, ¿qué significa la expresión () ? ¿Es un tipo? ¿Qué son las variables de tipo () ? ¿Para qué se usa y cuándo se necesita?


Como han dicho otros, () en Haskell es tanto el nombre del tipo de "unidad" como el único valor de dicho tipo.

Una de las cosas confusas al pasar de la programación imperativa a Haskell es que la forma en que los idiomas tratan el concepto de "nada" es diferente. Lo que es más confuso es el vocabulario, porque los lenguajes imperativos y Haskell usan el término "vacío" para significar cosas diametralmente diferentes.

En un lenguaje imperativo, una "función" (que puede no ser una verdadera función matemática) puede tener "vacío" como su tipo de retorno, como en este ejemplo de pseudocódigo:

void sayHello() { printLn("Hello!"); }

En este caso, void significa que la "función", si se devuelve, no producirá un valor de resultado. (La otra posibilidad es que la función no pueda regresar; puede hacer un ciclo para siempre, o fallar con un error o excepción).

En Haskell, sin embargo, todas las funciones (y las acciones IO ) deben producir un resultado. Entonces, cuando escribimos una acción IO que no produce ningún valor de retorno interesante, hacemos que devuelva () :

sayHello :: IO () sayHello = putStrLn "Hello!"

Las acciones posteriores simplemente ignorarán el valor del resultado () .

Ahora, probablemente no necesite preocuparse demasiado por esto, pero hay un lugar donde esto se vuelve confuso, que es que en Haskell hay un tipo llamado Void , pero significa algo completamente diferente del imperativo void programación. Debido a esto, la palabra "vacío" se convierte en un campo minado al comparar Haskell y los idiomas imperativos, porque el significado es completamente diferente cuando cambias de paradigma.

En Haskell, Void es un tipo que no tiene ningún valor. La mayor consecuencia de esto es que en Haskell una función con el tipo de retorno Void nunca puede regresar, solo puede fallar con un error o un bucle para siempre. ¿Por qué? Debido a que la función habría producido un valor de tipo Void para regresar, pero no existe tal valor.

Sin embargo, esto no es relevante hasta que esté trabajando con algunas técnicas más avanzadas, por lo que no necesita preocuparse más que por tener cuidado con la palabra "vacío".

Pero la lección más importante es que el imperativo y los conceptos de Haskell de "ningún valor de retorno" son diferentes. Haskell distingue entre:

  1. Cosas que pueden regresar pero cuyo resultado no tendrá ninguna información (el tipo () );
  2. Cosas que no pueden regresar, sin importar qué (el tipo Void ).

El void imperativo corresponde al primero, y no al segundo.


Como han dicho otros, es el tipo de unidad que tiene un valor llamado unidad. En la sintaxis de Haskell, esto se expresa fácilmente, aunque de manera confusa, como () :: () . Podemos hacer nuestro propio muy fácilmente también.

data Unit = Unit >>> :t Unit :: Unit Unit :: Unit >>> :t () :: () () :: ()

Se escribe como () porque se comporta de manera muy parecida a una "tupla vacía". Hay razones teóricas por las que esto se sostiene, pero honestamente también tiene un gran sentido intuitivo.

A menudo se usa como argumento para un constructor de tipo como IO o ST cuando es el contexto del valor que es interesante, no el valor en sí. Esto es intuitivamente cierto porque si le digo que tengo un valor de tipo () entonces no necesita saber nada más, ¡solo hay uno de ellos!

putStrLn :: String -> IO () -- the return type is unimportant, -- we just want the *effect* map (const ()) :: [a] -> [()] -- this destroys all information about a list -- keeping only the *length* >>> [ (), (), () ] :: [()] -- this might as well just be the number `3` -- there is nothing else interesting about it forward :: [()] -> Int -- we have a pair of isomorphisms even forward = length backward :: Int -> [()] backward n = replicate n ()


Es tanto un tipo como un valor. () es un tipo especial " unidad pronunciada", y tiene un valor: () , también unidad pronunciada. Es esencialmente el mismo que el tipo void en Java o C / C ++. Si está familiarizado con Python, piense en él como el NoneType que tiene el singleton None .

Es útil cuando desea denotar una acción que no devuelve nada. Se utiliza más comúnmente en el contexto de las mónadas, como la mónada IO . Por ejemplo, si tuvieras la siguiente función:

getVal :: IO Int getVal = do putStrLn "Enter an integer value:" n <- getLine return $ read n

Y por alguna razón, decidió que solo quería molestar al usuario y tirar el número que acaba de pasar:

getValAnnoy :: IO () getValAnnoy = do _ <- getVal return () -- Returns nothing

Sin embargo, el return es solo una función de Monad , por lo que podríamos abstraerlo un poco más.

throwAwayResult :: Monad m => m a -> m () throwAwayResult action = do _ <- action return ()

Entonces

getValAnnoy = throwAwayResult getVal

Sin embargo, no tiene que escribir esta función usted mismo, ya existe en Control.Monad como la función void que es aún menos restrictiva y funciona en Functor s:

void :: Functor f => f a -> f () void fa = fmap (const ()) fa

¿Por qué funciona en Functor lugar de Monad ? Bueno, para cada instancia de Monad , puede escribir la instancia de Functor como

instance Monad m => Functor m where fmap f m = m >>= return . f

Pero no puedes hacer una Monad con cada Functor . Es como un cuadrado es un rectángulo, pero un rectángulo no siempre es un cuadrado, las mónadas forman un subconjunto de Functors.


Es tanto un tipo como un valor.

Es tipo de unidad , el tipo que tiene un solo valor. En Haskell, su nombre y único valor se parecen a una tupla vacía: () .