Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What do parentheses () used on their own mean?

Tags:

I read in learn you haskell that

Enum members are sequentially ordered types ... Types in this class: (), Bool, Char ...

Also it appears in some signatures:

putChar  ::    Char -> IO ()

It is very difficult to find info about it in Google as the answers refer to problems of the "common parentheses" (use in function calls, precedence problems and the like).

Therefore, what does the expression () means? Is it a type? What are variables of type ()? What is used for and when is it needed?

like image 463
cibercitizen1 Avatar asked Dec 04 '13 16:12

cibercitizen1


People also ask

What does it mean to use parentheses?

When you use parentheses to set off material in a sentence, you say that the material is “in parenthesis.” Put something in parentheses if it's a comment, an afterthought, or additional information that is possibly interesting but not essential to the subject.

What effect do the parentheses () have?

Parentheses also signify a break in thought, but they mark an addition of information rather than an interruption like dashes do. Rather than a surprise (like dashes), parentheses are a gentler insertion in your sentence.

What do parentheses brackets mean?

Parentheses are smooth and curved ( ), brackets are square [ ], and braces are curly { }. In mathematics, they are mostly used for order of operations. The innermost parentheses are calculated first, followed by the brackets that form the next layer outwards, followed by braces that form a third layer outwards.

What does it mean when a number is in parentheses by itself?

The most important thing to note here: When talking about the order of operations, "parentheses" just means that any calculations completely inside parentheses should be done first. e.g for 10 * (6 + 3), we add 6 and 3 first.


1 Answers

It is both a type and a value. () is a special type "pronounced" unit, and it has one value: (), also pronounced unit. It is essentially the same as the type void in Java or C/C++. If you're familiar with Python, think of it as the NoneType which has the singleton None.

It is useful when you want to denote an action that doesn't return anything. It is most commonly used in the context of Monads, such as the IO monad. For example, if you had the following function:

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

And for some reason you decided that you just wanted to annoy the user and throw away the number they just passed in:

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

However, return is just a Monad function, so we could abstract this a bit further

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

Then

getValAnnoy = throwAwayResult getVal

However, you don't have to write this function yourself, it already exists in Control.Monad as the function void that is even less constraining and works on Functors:

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

Why does it work on Functor instead of Monad? Well, for each Monad instance, you can write the Functor instance as

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

But you can't make a Monad out of every Functor. It's like how a square is a rectangle but a rectangle isn't always a square, Monads form a subset of Functors.

like image 164
bheklilr Avatar answered Sep 23 '22 04:09

bheklilr