
On 6/22/06, Sara Kenedy
Hello all,
Now I am trying with the function of polymorphic type: This function returns the Nth element of list with type a. I try it as below.
getNthElem :: Int -> [a] -> Maybe a getNthElemt _ [] = Nothing getNthElem 0 _ = Nothing getNthElem n s | n > length s = Nothing | otherwise = Just ((drop (n-1) (take n s))!!0)
getNthElem 2 ["a","b","c"] Just "b"
However, I do not satisfy with this function because I want to return the Nth element of type a, not (Maybe a). For example, I want this function: getNthElem :: Int -> [a] -> a
But, I do not know how to define the empty element of type a.
Not all types (especially numbers) have an empty element (what does that even mean?). Suppose you have a list [0, 1, -2, -1, 2] and you try getNthElemt 4 and your program assumes that the empty element for integers is 0. How can you tell that 0 from the 0 at the beginning of the list [0, 1, 2]? Think really hard about what you are asking and you will see why Maybe a takes the type a and extends it, in a way, with an empty element, Nothing. To convert it from Maybe a to a, try, e.g. fromJust (Just 4) ====> 4 (it will give exceptions when Nothing shows up).
getNthElemt _ [] = ???? getNthElem 0 _ = ????
One possiblity is to make a class called empty with a single member:
class Empty a where empty :: a instance Empty [a] where -- this also makes "" = empty for String empty = [] instance Empty Maybe a where -- is this desirable? empty = Nothing instance Integer where -- or this? empty = 0 ...
and then add the constraint to your function:
getNthElem :: Empty a => Int -> [a] -> a getNthElem :: Int -> [a] -> Maybe a getNthElemt _ [] = empty getNthElem 0 _ = empty getNthElem n s | n > length s = empty | otherwise = ((drop (n-1) (take n s))!!0)
but you need overlapping instances to instantiate [a]. Or you could use MonadPlus and mzero instead of Empty and empty, but that would only work for List, Maybe and other monads and not for Integer, etc. Note that in a dynamic language the same thing happens. In python 4 + None raises an exception. I don't think it's possible to get away from this whole "failure" concept (except silently ignore it---in perl 4+null yields 4 but is that always the right behavior in all situations? It makes bugs really hard to find.) Jared. -- http://www.updike.org/~jared/ reverse ")-:"