Pongo una restricción en el tipo de argumento de una función en lugar de poner el tipo de la función. 
Pensé que esto daría un error de sintaxis o agregaría más información al tipo de función. 
Pero parece que la restricción se ignora por completo.
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE RankNTypes #-}
test :: a -> String
test (n :: (Num a, Ord a) => a) =
    if n > 10 then "Hello"
    else "World"
main = print "Hello World"
Esto da el siguiente tipo de error:
Test3.hs:6:8: error:
    • No instance for (Num a) arising from a use of ‘n’
      Possible fix:
        add (Num a) to the context of
          the type signature for:
            test :: forall a. a -> String
    • In the first argument of ‘(>)’, namely ‘n’
      In the expression: n > 10
      In the expression: if n > 10 then "Hello" else "World"
  |
6 |     if n > 10 then "Hello"
  |        ^
Test3.hs:6:8: error:
    • No instance for (Ord a) arising from a use of ‘>’
      Possible fix:
        add (Ord a) to the context of
          the type signature for:
            test :: forall a. a -> String
    • In the expression: n > 10
      In the expression: if n > 10 then "Hello" else "World"
      In an equation for ‘test’:
          test (n :: (Num a, Ord a) => a)
            = if n > 10 then "Hello" else "World"
  |
6 |     if n > 10 then "Hello"
  |  
¿Qué significa realmente poner una restricción en el tipo de argumento?
EDITAR:
¿Por qué esto necesita RankNTypesextensión? 
No es necesario si elimino la (Num a, Ord a) =>restricción.

Respuestas:
Esta es una instancia bastante exótica de subsunción polimórfica, como se describe aquí , que interactúa con la subsunción de restricción.
Si un tipo
asubsumeb, entoncesexp :: aimplicaexp :: ben el lenguaje superficial. Un ejemplo particular de subsunción es quef :: forall a. a -> aimplicaf :: Int -> Int. Además, tenemosn :: Intimplican :: c => Intpara cualquiercrestricción.Sin embargo, en el lenguaje central no hay subsunción en absoluto. Cada caso de subsunción en el lenguaje de superficie debe traducirse a lambdas y aplicaciones explícitas. Además,
c => asimplemente se conviertec -> a, y el uso de funciones restringidas se traduce en la aplicación de funciones simplesf :: c => apara algunosinst :: c. Por lo tanto, sef :: forall a. a -> avuelvef @Int :: Int -> Inty sen :: Intvuelve\_ -> n :: c -> Int.Un caso raramente utilizado es la regla de subsunción contravariante para funciones. El siguiente es un código válido:
Esto se traduce a
Funciona de manera similar con la subsunción de restricción:
Que se traduce a
Acercándonos a la pregunta original, si tenemos
como definición superior, su tipo inferido es
forall a. (Eq a => a) -> Bool. Sin embargo, podemos tener cualquier tipo de anotación para lafcual se incluye el tipo inferido. Entonces podemos tener:Y GHC sigue feliz. El código original
es equivalente a la siguiente versión ligeramente más clara:
El error de tipo, que se obtiene es simplemente porque
nes realmente una función con dos argumentos, uno tiene el tipoNum ay el otroOrd a, y ambos de estos argumentos son los registros que contienenNumyOrdmétodos. Sin embargo, dado que no hay tales instancias en el alcance de la definición, no puede usarlasncomo un número. La traducción se convertirían > 10a(>) inst (n inst) (10 inst), dondeinst :: Num a, pero no existeinst, por lo que no podemos traducir.Por lo tanto, en el cuerpo del
testcódigo todavía se verifica conn :: (Num a, Ord a) => a). Sin embargo, si solo devolvemos "Hola" sin usarn, de manera similar alfcaso anterior , obtenemos un tipo inferido que subsume elforall a. a -> Stringtipo de anotación. La subsunción se realiza luego en la salida de traducción reemplazando cada aparición denen el cuerpo detestcon\_ -> n. Pero comonno ocurre en el cuerpo, la traducción no hace nada aquí.fuente