2016-10-31 3 views
4

Когда я вхожу :t 4 в GHCI яПочему ghci выдает (Num a) => a для: t 4 и не (Ord a) => a?

Prelude> :t 4 
4 :: Num t => t 

Я понимаю, почему 4 не только Int или Integer, и что это infered снизу вверх, но я не понимаю, почему 4 не показан как Ord t => t или даже более правильно что-то вроде этого:

4 :: (Ord t || Num t) => t 

Поскольку 4 является одновременно Ord и Num но Ord и Num не имеют никакого отношения к ...

Так почему же :t 4 только выход Num?

+0

Это описано в [отчете haskell] (https://www.haskell.org/onlinereport/haskell2010/haskellch6.html#x13-1360006.4.1) – Lee

+4

Предположим, что я дал '4' тип' Ord t = > t'. Теперь я отмечаю, что 'Bool' является экземпляром' Ord'. Поэтому '4 :: Bool'. Если '4 :: Bool' будет' True' или 'False' и почему? –

+0

@ Lee Btw, есть аналогичный вопрос о правилах по умолчанию для типа: https://stackoverflow.com/questions/39251728/ghci-randomio-type-inference Я попытался ответить на него и понять отчет, но до сих пор не имеет четкого представления. Возможно, более опытные пользователи _Haskell_ могут помочь :) – Shersh

ответ

9

Не все типы с экземплярами для Num также экземпляры для Ord, и вам нужно только fromInteger часть Num иметь перегруженные числовые литералы Haskell имеет. Например, Complex от Data.Complex имеет экземпляр Num, но не Ord. В этом случае 4 является не a Ord.

ghci> import Data.Complex 
ghci> let x = 1 :: Complex Double 
ghci> let y = 2 :: Complex Double 
ghci> x < y 
<interactive> 
    * No instance for (Ord (complex Double)) arising from use of `<' 
    * In the expression: x < y 
     In the equation for `it': it = x < y 
ghci> 

Как отметил @Lee, это поведение описано в report.

+0

Обратите внимание, что вы объяснили, почему тип не является '(Ord t, Num t) => t', а не почему это не' (Ord t || Num t) => t' (это недопустимый синтаксис, но, я полагаю, подразумевается, что «t может быть« Ord' * или * a 'Num'). – sepp2k

+0

@ sepp2k Это правда - я не интерпретировал' Это так, я думаю, я косвенно отвечаю на это ... – Alec

+0

Ok thx. Вещь с 'fromIntegral' в Link, предоставленная @Lee, была очень полезной. Еще более полезной была ссылка на раздел [3.4 .3] (https://www.haskell.org/onlinereport/haskell2010/haskellch4.html#x10-790004.3.4). Поэтому, когда я пишу '(3 <4)': для вывода фактического типа '4', компилятор должен найти Тип, который удовлетворяет '(Num t, Ord t) => t', который может быть одним из' Int', 'Integer',' Float', 'Double' (или даже больше с внешними модулями) Это неоднозначно и приведет к ошибке. Но для Num эти двусмысленности разрешаются defaul ting to (в этом случае) Integer. – Databyte

Смежные вопросы