Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p><strong>[edit from Author, 6 years later] This is a needlessly long answer, and I'm not sure why it was accepted. Use <code>maybe</code> or <code>Data.Maybe.fromMaybe</code> as suggested in the highest upvoted answer. What follows is more of a thought experiment rather than practical advice.</strong></p> <p>So you're trying to create a function that works for a bunch of different types. This is a good time to make a class. If you've programmed in Java or C++, a class in Haskell is kind of like an interface in those languages.</p> <pre><code>class Nothingish a where nada :: a </code></pre> <p>This class defines a value <code>nada</code>, which is supposed to be the class's equivalent of <code>Nothing</code>. Now the fun part: making instances of this class!</p> <pre><code>instance Nothingish (Maybe a) where nada = Nothing </code></pre> <p>For a value of type <code>Maybe a</code>, the Nothing-like value is, well, <code>Nothing</code>! This will be a weird example in a minute. But before then, let's make lists an instance of this class too.</p> <pre><code>instance Nothingish [a] where nada = [] </code></pre> <p>An empty list is kind of like Nothing, right? So for a String (which is a list of Char), it will return the empty string, <code>""</code>.</p> <p>Numbers are also an easy implementation. You've already indicated that 0 obviously represents "Nothingness" for numbers.</p> <pre><code>instance (Num a) =&gt; Nothingish a where nada = 0 </code></pre> <p>This one will actually not work unless you put a special line at the top of your file</p> <pre><code>{-# LANGUAGE FlexibleInstances, UndecidableInstances, OverlappingInstances #-} </code></pre> <p>Or when you compile it you can set the flags for these language pragmas. Don't worry about them, they're just magic that makes more stuff work.</p> <p>So now you've got this class and these instances of it...now let's just re-write your function to use them!</p> <pre><code>eliminate :: (Nothingish a) =&gt; Maybe a -&gt; a eliminate (Just a) = a eliminate Nothing = nada </code></pre> <p>Notice I only changed <code>0</code> to <code>nada</code>, and the rest is the same. Let's give it a spin!</p> <pre><code>ghci&gt; eliminate (Just 2) 2 ghci&gt; eliminate (Just "foo") "foo" ghci&gt; eliminate (Just (Just 3)) Just 3 ghci&gt; eliminate (Just Nothing) Nothing ghci&gt; :t eliminate eliminate :: (Nothingish t) =&gt; Maybe t -&gt; t ghci&gt; eliminate Nothing error! blah blah blah...**Ambiguous type variable** </code></pre> <p>Looks great for values and stuff. Notice the (Just Nothing) turns into Nothing, see? That was a weird example, a Maybe in a Maybe. Anyways...what about <code>eliminate Nothing</code>? Well, the resultant type is ambiguous. It doesn't know what we are expecting. So we have to tell it what type we want.</p> <pre><code>ghci&gt; eliminate Nothing :: Int 0 </code></pre> <p>Go ahead and try it out for other types; you'll see it gets <code>nada</code> for each one. So now, when you use this function with your <code>combine</code> function, you get this:</p> <pre><code>ghci&gt; let combine a b c = (eliminate a, eliminate b, eliminate c) ghci&gt; combine (Just 2) (Just "foo") (Just (Just 3)) (2,"foo",Just 3) ghci&gt; combine (Just 2) Nothing (Just 4) error! blah blah Ambiguous Type blah blah </code></pre> <p>Notice you still have to indicate what type your "Nothing" is, or indicate what return type you expect.</p> <pre><code>ghci&gt; combine (Just 2) (Nothing :: Maybe Int) (Just 4) (2,0,4) ghci&gt; combine (Just 2) Nothing (Just 4) :: (Int, Int, Int) (2,0,4) </code></pre> <p>Or, you could restrict the types that your function allows by putting its type signature explicitly in the source. This makes sense if the logical use of the function would be that it is only used with parameters of the same type.</p> <pre><code>combine :: (Nothingish a) =&gt; Maybe a -&gt; Maybe a -&gt; Maybe a -&gt; (a,a,a) combine a b c = (eliminate a, eliminate b, eliminate c) </code></pre> <p>Now it only works if all three Maybe things are the same type. That way, it will infer that the <code>Nothing</code> is the same type as the others.</p> <pre><code>ghci&gt; combine (Just 2) Nothing (Just 4) (2,0,4) </code></pre> <p>No ambiguity, yay! But now it is an error to mix and match, like we did before.</p> <pre><code>ghci&gt; combine (Just 2) (Just "foo") (Just (Just 3)) error! blah blah Couldn't match expected type blah blah blah blah blah against inferred type blah blah </code></pre> <p>Well, I think that was a sufficiently long and overblown answer. Enjoy.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload