разница между 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 …
.
другими словами, Вот как вы можете определить ==
это уже существует для Maybe
s:
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
.