Haskell - Tipos e classe de tipo
Haskell é uma linguagem funcional e é rigidamente tipada, o que significa que o tipo de dados usado em todo o aplicativo será conhecido pelo compilador no momento da compilação.
Classe de tipo embutido
Em Haskell, cada afirmação é considerada uma expressão matemática e a categoria desta expressão é chamada de Type. Você pode dizer que "Tipo" é o tipo de dados da expressão usada em tempo de compilação.
Para saber mais sobre o Type, usaremos o comando ": t". De uma forma genérica,Type pode ser considerado um valor, enquanto Type Classpode ser considerado como um conjunto de tipos semelhantes. Neste capítulo, aprenderemos sobre os diferentes tipos embutidos.
Int
Inté uma classe de tipo que representa os dados de tipos inteiros. Cada número inteiro dentro do intervalo de 2147483647 a -2147483647 está sob oIntclasse de tipo. No exemplo a seguir, a funçãofType() irá se comportar de acordo com seu tipo definido.
fType :: Int -> Int -> Int
fType x y = x*x + y*y
main = print (fType 2 4)
Aqui, definimos o tipo de função fType() Como int. A função leva doisint valores e retorna um intvalor. Se você compilar e executar este trecho de código, ele produzirá a seguinte saída -
sh-4.3$ ghc -O2 --make *.hs -o main -threaded -rtsopts
sh-4.3$ main
20
Inteiro
Integer pode ser considerado um superconjunto de Int. Este valor não é limitado por nenhum número, portanto, um inteiro pode ter qualquer comprimento sem qualquer limitação. Para ver a diferença básica entreInt e Integer tipos, vamos modificar o código acima da seguinte maneira -
fType :: Int -> Int -> Int
fType x y = x*x + y*y
main = print (fType 212124454 44545454454554545445454544545)
Se você compilar o trecho de código acima, a seguinte mensagem de erro será lançada -
main.hs:3:31: Warning:
Literal 44545454454554545445454544545 is out of the Int range -
9223372036854775808..9223372036854775807
Linking main ...
Este erro ocorreu porque nossa função fType () esperava um valor de tipo Int e estamos passando algum valor de tipo Int realmente grande. Para evitar este erro, vamos modificar o tipo "Int" para "Integer" e observar a diferença.
fType :: Integer -> Integer -> Integer
fType x y = x*x + y*y
main = print (fType 212124454 4454545445455454545445445454544545)
Agora, ele produzirá a seguinte saída -
sh-4.3$ main
1984297512562793395882644631364297686099210302577374055141
Flutuador
Dê uma olhada no seguinte trecho de código. Mostra como funciona o tipo Float em Haskell -
fType :: Float -> Float -> Float
fType x y = x*x + y*y
main = print (fType 2.5 3.8)
A função assume dois valores flutuantes como entrada e produz outro valor flutuante como saída. Quando você compila e executa este código, ele produzirá a seguinte saída -
sh-4.3$ main
20.689999
Duplo
Doubleé um número de ponto flutuante com precisão dupla no final. Dê uma olhada no seguinte exemplo -
fType :: Double -> Double -> Double
fType x y = x*x + y*y
main = print (fType 2.56 3.81)
Quando você executa o trecho de código acima, ele irá gerar a seguinte saída -
sh-4.3$ main
21.0697
Bool
Boolé um tipo booleano. Pode ser verdadeiro ou falso. Execute o seguinte código para entender como o tipo Bool funciona em Haskell -
main = do
let x = True
if x == False
then putStrLn "X matches with Bool Type"
else putStrLn "X is not a Bool Type"
Aqui, estamos definindo uma variável "x" como um Bool e comparando-a com outro valor booleano para verificar sua originalidade. Ele produzirá a seguinte saída -
sh-4.3$ main
X is not a Bool Type
Caracteres
Char representam personagens. Qualquer coisa dentro de uma aspa simples é considerada um personagem. No código a seguir, modificamos nossofType() função para aceitar o valor Char e retornar o valor Char como saída.
fType :: Char-> Char
fType x = 'K'
main = do
let x = 'v'
print (fType x)
O trecho de código acima chamará fType() funcionar com um charvalor de 'v', mas retorna outro valor char, ou seja, 'K'. Aqui está o resultado -
sh-4.3$ main
'K'
Observe que não vamos usar esses tipos explicitamente porque Haskell é inteligente o suficiente para capturar o tipo antes que ele seja declarado. Nos capítulos subsequentes deste tutorial, veremos como diferentes tipos e classes de tipo tornam Haskell uma linguagem fortemente tipada.
Classe de tipo EQ
EQclasse de tipo é uma interface que fornece a funcionalidade para testar a igualdade de uma expressão. Qualquer classe de tipo que deseja verificar a igualdade de uma expressão deve fazer parte desta classe de tipo de EQ.
Todas as classes de tipo padrão mencionadas acima fazem parte deste EQclasse. Sempre que estamos verificando qualquer igualdade usando qualquer um dos tipos mencionados acima, estamos na verdade fazendo uma chamada paraEQ classe de tipo.
No exemplo a seguir, estamos usando o EQ Digite internamente usando a operação "==" ou "/ =".
main = do
if 8 /= 8
then putStrLn "The values are Equal"
else putStrLn "The values are not Equal"
Isso produzirá a seguinte saída -
sh-4.3$ main
The values are not Equal
Classe de tipo ord
Ordé outra classe de interface que nos dá a funcionalidade de ordenação. Todostypes que temos usado até agora são parte disso Ordinterface. Como a interface EQ, a interface Ord pode ser chamada usando ">", "<", "<=", "> =", "compare".
Veja abaixo o exemplo em que usamos a funcionalidade de “comparação” dessa classe de tipo.
main = print (4 <= 2)
Aqui, o compilador Haskell verificará se 4 é menor ou igual a 2. Como não é, o código produzirá a seguinte saída -
sh-4.3$ main
False
exposição
Showtem a funcionalidade de imprimir seu argumento como uma String. Qualquer que seja seu argumento, ele sempre imprime o resultado como uma String. No exemplo a seguir, imprimiremos a lista inteira usando esta interface. "show" pode ser usado para chamar esta interface.
main = print (show [1..10])
Ele produzirá a seguinte saída no console. Aqui, as aspas duplas indicam que é um valor do tipo String.
sh-4.3$ main
"[1,2,3,4,5,6,7,8,9,10]"
Ler
Readinterface faz a mesma coisa que Mostrar, mas não imprimirá o resultado no formato String. No código a seguir, usamos oread interface para ler um valor de string e convertê-lo em um valor Int.
main = print (readInt "12")
readInt :: String -> Int
readInt = read
Aqui, estamos passando uma variável String ("12") para o readIntmétodo que, por sua vez, retorna 12 (um valor Int) após a conversão. Aqui está o resultado -
sh-4.3$ main
12
Enum
Enumé outro tipo de classe Type que ativa a funcionalidade sequencial ou ordenada em Haskell. Esta classe de tipo pode ser acessada por comandos comoSucc, Pred, Bool, Charetc.
O código a seguir mostra como encontrar o valor do sucessor de 12.
main = print (succ 12)
Ele produzirá a seguinte saída -
sh-4.3$ main
13
Limitado
Todos os tipos com limites superior e inferior vêm sob esta classe de tipo. Por exemplo,Int Os dados de tipo têm limite máximo de "9223372036854775807" e limite mínimo de "-9223372036854775808".
O código a seguir mostra como Haskell determina o limite máximo e mínimo do tipo Int.
main = do
print (maxBound :: Int)
print (minBound :: Int)
Ele produzirá a seguinte saída -
sh-4.3$ main
9223372036854775807
-9223372036854775808
Agora, tente encontrar o limite máximo e mínimo dos tipos Char, Float e Bool.
Num
Esta classe de tipo é usada para operações numéricas. Tipos como Int, Integer, Float e Double estão nesta classe de tipo. Dê uma olhada no seguinte código -
main = do
print(2 :: Int)
print(2 :: Float)
Ele produzirá a seguinte saída -
sh-4.3$ main
2
2.0
Integrante
Integralpode ser considerada como uma subclasse da classe Num Type. A classe Num Type contém todos os tipos de números, enquanto a classe do tipo Integral é usada apenas para números inteiros. Int e Integer são os tipos dessa classe de tipo.
Flutuando
Como Integral, Floating também faz parte da classe Num Type, mas contém apenas números de ponto flutuante. Conseqüentemente,Float e Double vêm sob este tipo de classe.
Classe de tipo personalizado
Como qualquer outra linguagem de programação, Haskell permite que os desenvolvedores definam tipos definidos pelo usuário. No exemplo a seguir, criaremos um tipo definido pelo usuário e o usaremos.
data Area = Circle Float Float Float
surface :: Area -> Float
surface (Circle _ _ r) = pi * r ^ 2
main = print (surface $ Circle 10 20 10 )
Aqui, criamos um novo tipo chamado Area. Em seguida, estamos usando este tipo para calcular a área de um círculo. No exemplo acima, "superfície" é uma função que levaArea como entrada e produz Float como a saída.
Lembre-se de que "dados" é uma palavra-chave aqui e todos os tipos definidos pelo usuário em Haskell sempre começam com uma letra maiúscula.
Ele produzirá a seguinte saída -
sh-4.3$ main
314.15927