¿Cómo lidiar cómodamente con el sistema de tipos en Haskell?

El sistema de tipos de Haskell es poderoso y apreciado por su rigurosidad matemática y solidez lógica, por otro lado, algo tan ingenuo como a continuación me hace preguntarme por qué no funciona como lo espera la intuición.

P.ej. porque no puedoInt ser convertido aNum enx3 perof1 aceptarInt contra la firmaNum?

Prelude> let x1 = 1
Prelude> :t x1
x1 :: Num a => a

Prelude> let x2 = 1 :: Int
Prelude> :t x2
x2 :: Int

Prelude> let x3 = (1 :: Int) :: Num a => a
Couldn't match expected type ‘a1’ with actual type ‘Int’

Prelude> let f1 :: Num a => a -> a; f1 = id
Prelude> :t f1 (1 :: Int)
f1 (1 :: Int) :: Int

Prelude> let f2 :: Int -> Int; f2 = id
Prelude> :t f2 1
f2 1 :: Int

Prelude> let f3 :: Num a => a -> Int; f3 = id

Prelude> let f4 :: Num a => Int -> a; f4 = id
Couldn't match type ‘a’ with ‘Int’

Sabía que uno finalmente debería aprender la teoría subyacente, p.Sistema de tipo HM para lidiar cómodamente con el sistema de tipos, e incluso encontré algunos escritos agradables, p.1, 2, 3 y4 por desmitificarlo. ¿Qué más te gustaría recomendar si alguna vez te cruzaste y superaste este desafío?

@EDITAR

Prelude> let f5 x5 = x5::Int
Prelude> :t f5
f5 :: Int -> Int

Prelude> let f6 x6 = x6::Num a => a
Couldn't match expected type ‘a1’ with actual type ‘t’

Primero,x6 debe haber sido un supertipo deNum es decirNum en sí mismo cuandox6 es tipo anotado conNum. Sin embargo, las anotaciones de tipo concatenar paraNum despuésInt de(x6::Int)::Num a => a no se unirá si luego abatidox6 deNum aInt. Por lo tanto, el primer tipo inferidoNum dex6 No está satisfecho aquí.