Como lidar confortavelmente com o sistema de tipos em Haskell?
O sistema de tipos de Haskell é poderoso e apreciado por seu rigor matemático e solidez lógica; por outro lado, algo tão ingênuo como abaixo me faz pensar por que ele não funciona como o esperado pela intuição?
Por exemplo. por que nãoInt
ser convertido paraNum
emx3
masf1
aceitarInt
contra a assinaturaNum
?
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’
Eu sabia que alguém deveria finalmente aprender a teoria subjacente, p.Sistema tipo HM para lidar confortavelmente com o sistema de tipos e até encontrou alguns textos interessantes, por exemplo1, 2, 3 e4 por desmistificar isso. O que mais você gostaria de recomendar se alguma vez cruzasse e vencesse esse desafio?
@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’
Primeiro,x6
deve ter sido um supertipo deNum
isso éNum
quandox6
é do tipo anotado comNum
. No entanto, as anotações de tipo concatenadas paraNum
depois deInt
do(x6::Int)::Num a => a
não será unido se então abatermosx6
deNum
paraInt
. Portanto, o primeiro tipo inferidoNum
dox6
está insatisfeito aqui.