Обратите внимание, что если вы просто спрашиваете, можно ли сделать выражение 3 == 5
полиморфным в типах 3
и 5
, ответ - да.Подпись должна быть дана явно с помощью некоторых языковых расширений, но следующее определение является полиморфным:
{-# LANGUAGE AllowAmbiguousTypes #-}
{-# LANGUAGE ScopedTypeVariables #-}
module ThreeFive where
eq35 :: forall a . (Num a, Eq a) => Bool
eq35 = (3 :: a) == 5
В качестве альтернативы, вы можете использовать TypeApplications
:
eq35' :: forall a . (Num a, Eq a) => Bool
eq35' = (==) @a 3 5
Теперь,GHCi сообщает тип eq35
как Bool
, но это ложь, как вы можете видеть, добавив флаг +v
:
> :type eq35
eq35 :: Bool
> :type +v eq35
eq35 :: (Num a, Eq a) => Bool
или доказав это:
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
-- Holistic number are all equal
newtype Holistic = Holistic Int deriving (Num)
instance Eq Holistic where
_ == _ = True
main = do print (eq35 @Int)
print (eq35 @Holistic)
и запуск этой команды выведет False
и True
.
Я не вижу никакой комбинации языковых расширений, которая позволила бы GHC автоматически выводит более общий тип для 3 == 5
, чем True
при отсутствии явных сигнатур типов.Точно так же, как бы полиморфными не были x
и y
, x == y
будет либо по умолчанию установлен в мономорфный тип, либо отклонен, если вы не используете явную подпись, подобную приведенной выше.