разница между isNothing и (==ничего) в Haskell?

Я смущен тем, почему две функции ниже включают Nothing иначе:

coalesce  m1 m2 = if  isNothing m1 then m2 else m1

coalesce' m1 m2 = if  (m1 == Nothing) then m2 else m1

первый имеет вид:

λ> :t coalesce
coalesce :: Maybe a -> Maybe a -> Maybe a

как и ожидалось. Но у второго есть:

λ> :t coalesce'
coalesce' :: Eq a => Maybe a -> Maybe a -> Maybe a

почему через (==Nothing) вводим Eq a ограничения?

(GHC 8.2.2)

3 ответов


== функция Eq a => a -> a -> Bool. Вы делаете один из его операндов Nothing, Так что a это Maybe b для некоторого типа b, но это Eq a ограничение по-прежнему действует – в Maybe b есть Eq экземпляра. Maybe b содержит определение для такого экземпляра – Eq (Maybe b) для всех Eq b.

другими словами, == - это просто функция, и она не знает заранее, что вы предоставляете Nothing в качестве аргумента. Это знает только он некоторые Maybe a, и он должен иметь возможность сравнивать равенство, если это случается Just ….

другими словами, Вот как вы можете определить == это уже существует для Maybes:

equals a b = case a of
    Nothing -> isNothing b
    Just x -> case b of
        Nothing -> False
        Just y -> x == y

обратите внимание, как x == y кажется, смысл должен быть Eq экземпляр для типа x и y.


потому что типа == и

(==) :: (Eq a) => a -> a -> Bool

ваше второе определение (coalesce') использует ==, поэтому он наследует Eq ограничение на его аргументы из ==.


строго говоря coalesce' использует == по значениям типа Maybe a, но есть экземпляр

instance (Eq a) => Eq (Maybe a) where ...

так Eq (Maybe a) ограничения Eq a, потому что это то, что необходимо для поддержки == on Maybe a.


давайте сначала стремиться разработать