qed
qed

Reputation: 23134

Return an empty object of a certain type in Haskell

Here is what I am trying to do:

justExpose :: Maybe a -> a
justExpose (Just x) = x
justExpose Nothing = -- an empty object of type a

Any ideas?

Upvotes: 2

Views: 1934

Answers (4)

Heimdell
Heimdell

Reputation: 647

The Maybe a is the standard "type with empty value".

The way to extract that a is to perform a case-split or (better) use a

fromMaybe :: a -> Maybe a -> a  -- Defined in ‘Data.Maybe’

function, which is declared as

fromMaybe :: a -> Maybe a -> a
fromMaybe def optional = 
    case optional of
        Just value -> value
        Nothing    -> def

So, you just need to import Data.Maybe and call fromMaybe with an appropriate "empty object" of your choice (or what the task's domain requires there).

You can also leave it as Maybe a or even start to work in the Maybe monad, if you have many a -> Maybe b actions in the domain; the question here is the reason behind your "How do I...".

Upvotes: 4

Rufflewind
Rufflewind

Reputation: 8966

There is no such thing as an "empty object of a certain type" in Haskell (the gruesome "null" from various other languages). This is a necessity for type safety. If you ever want an "empty value" you are required to use Maybe.

There is however a thing known as ("bottom"), which in some ways similar but not really the same thing. Every type has as a possible value. Bottom manifests itself in several ways: typically as an error or as an infinite loop. For example, the following function yields bottom:

f x = f (x + 1)

This function will never return because it will loop indefinitely, and hence it's value is . Or you can raise an error:

justExpose :: Maybe a -> a
justExpose Nothing = error "there is Nothing"

But keep in mind such an error cannot be caught!* The error function (or similarly, the undefined value) should only be used when you know that it's not supposed to ever happen. (As a side note: the justExpose function is already available in the Data.Maybe module in the form of fromJust.)

[*] There are some tricks involving IO that can be used to catch it, but it can't be done in pure code without unsafePerformIO.

Upvotes: 3

DNA
DNA

Reputation: 42617

What you are asking for is a "null" in many other languages. Haskell deliberately does not provide such a thing, because it is unsafe.

You can get the code to compile as follows:

justExpose :: Maybe a -> a
justExpose (Just x) = x
justExpose Nothing = undefined

but if you call it with a Nothing you will get a runtime exception, because the value is, as the name suggests, undefined!

Update: As several people have pointed out, this functionality is provided by Data.Maybe.fromJust, as you can find by searching hoogle for your type signature Maybe a -> a

Upvotes: 4

Sibi
Sibi

Reputation: 48746

In case your type a has monoid structure in it, then you can use this:

import Data.Monoid

justExpose :: Monoid a => Maybe a -> a
justExpose (Just x) = x
justExpose Nothing = mempty

Some examples of this:

λ> let x = Nothing :: Maybe (Sum Int)
λ> justExpose x
Sum {getSum = 0}
λ> justExpose (Just [])
[]

But you should note that Maybe type is very useful in lots of situations.

Upvotes: 10

Related Questions