«Haskell позволяет сравнивать различные числовые типы», нет, это не так. На самом деле Haskell позволяет определять разные типы одними и теми же литералами. В частности, вы можете сделать
Prelude> let a = 3.7 :: Double
Prelude> let b = 1 :: Double
Prelude> a + b
4.7
OTOH, если бы я объявил их явно с конфликтующими типами, добавление не удалось бы:
Prelude> let a = 3.7 :: Double
Prelude> let b = 1 :: Int
Prelude> a + b
<interactive>:31:5:
Couldn't match expected type ‘Double’ with actual type ‘Int’
In the second argument of ‘(+)’, namely ‘b’
In the expression: a + b
Теперь Double не самый общий возможный тип ни для a, ни для b. На самом деле все числовые литералы полиморфны, но прежде чем произойдет какая-либо операция (например, сравнение на равенство), такой полиморфный тип должен быть привязан к конкретному мономорфному типу. Нравится,
Prelude> (3.0 :: Double) == (3 :: Double)
True
Поскольку ==, вопреки вашей предпосылке, на самом деле требует, чтобы обе стороны имели одинаковый тип, вы можете опустить подпись с любой стороны, ничего не меняя:
Prelude> 3.0 == (3 :: Double)
True
На самом деле, даже без какой-либо аннотации типа, GHCi по-прежнему будет обрабатывать обе стороны как Double. Это связано с типом по умолчанию — в данном конкретном случае Fractional является самым сильным ограничением для общего типа номера, а для Fractional тип по умолчанию — Double. OTOH, если бы обе стороны были целочисленными литералами, то GHCi выбрал бы Integer. Иногда это может иметь значение, например
Prelude> 10000000000000000 == 10000000000000001
False
но
Prelude> 10000000000000000 ==(10000000000000001 :: Double)
True
потому что в последнем случае последняя 1 теряется при ошибке с плавающей запятой.
person
leftaroundabout
schedule
01.08.2016
3и3.0имеют разные полиморфные типы, в выражении3 == 3.0им обоим присваивается один и тот же мономорфный тип перед вычислением равенства. Тип(==)говорит, что он должен принимать два аргумента одного типа:Eq a => a -> a -> Bool. Я подозреваю, что неправильное понимание этой тонкости и привело к вопросу. - person Daniel Wagner   schedule 01.08.2016length "abc" == 3.0. Это работает? - person n. 1.8e9-where's-my-share m.   schedule 01.08.2016