3

GHC.Exts exports the function the:

the ensures that all the elements of the list are identical and then returns that unique element

This function is partial as it throws an error in case not all elements of the list are equal.

How can I implement a function theMay that returns a Maybe instead?

duplode
  • 33,731
  • 7
  • 79
  • 150
Uli Köhler
  • 13,012
  • 16
  • 70
  • 120

2 Answers2

4

the is defined as follows:

the :: Eq a => [a] -> a
the (x:xs)
  | all (x ==) xs = x
  | otherwise     = error "GHC.Exts.the: non-identical elements"
the []            = error "GHC.Exts.the: empty list"

Based on this we can directly deduce theMay:

theMay :: Eq a => [a] -> Maybe a
theMay (x:xs)
  | all (x ==) xs = Just x
  | otherwise     = Nothing
theMay []         = Nothing
duplode
  • 33,731
  • 7
  • 79
  • 150
Uli Köhler
  • 13,012
  • 16
  • 70
  • 120
3

Same thing, but using the Maybe monad:

import Data.Maybe (listToMaybe)
import Control.Monad (guard)

theMay :: Eq a => [a] -> Maybe a
theMay xs = do
    x <- listToMaybe xs
    guard $ all (x ==) xs
    return x

(Apologies for golfing in your Q&A...)

duplode
  • 33,731
  • 7
  • 79
  • 150
  • No apologies required, your solution is quite interesting ;-) I basically built my solution on a modified `the`, whereare you built your solution from ground up. I thinkg it would be interesting to see which one is faster. Maybe both are inlined to an equivalent form !? – Uli Köhler Mar 27 '14 at 19:57
  • Both versions have complexity linear on the number of equal elements at the beginning of the list. In principle yours should be faster by a small constant factor, given that each monadic bind in the `Maybe` monad involves a test for `Nothing`. Of course the only way to be sure of such things is testing (or reading GHC core). – duplode Mar 28 '14 at 00:37