tutorial online funciones empresa descargar constructora company haskell

haskell - online - ¿Por qué ghci me da un tipo para "1++ 2" en lugar de hacer rabia?



haskell pdf (2)

GHCI me dará un tipo para 1 ++ 2 :

$ ghci GHCi, version 7.4.2: http://www.haskell.org/ghc/ :? for help Loading package ghc-prim ... linking ... done. Loading package integer-gmp ... linking ... done. Loading package base ... linking ... done. Prelude> :t 1 ++ 2 1 ++ 2 :: Num [a] => [a]

Pero esto está obviamente mal. Si trato de evaluarlo, en lugar de escribirlo, las cosas fallan correctamente:

Prelude> 1 ++ 2 <interactive>:3:1: No instance for (Num [a0]) arising from the literal `1'' Possible fix: add an instance declaration for (Num [a0]) In the first argument of `(++)'', namely `1'' In the expression: 1 ++ 2 In an equation for `it'': it = 1 ++ 2

¿Lo que da?


Pero esto está obviamente mal.

No, es completamente correcto.

El tipo de (++) es

(++) :: [a] -> [a] -> [a]

y el tipo de literales enteros es

1 :: Num n => n

Entonces, el tipo [a] que debe tener un argumento de (++) se unifica con el tipo Num n => n que tiene un literal, dando

1 ++ 2 :: Num [a] => [a]

y si tiene un tipo de lista con una instancia de Num , esa expresión también se puede evaluar.

Pero, de forma predeterminada, no hay ninguna instancia de Num para los tipos de lista disponibles, por lo que cuando intenta evaluarla, Ghci se queja de que no encuentra ninguna instancia de Num para [a] .

Por ejemplo:

Prelude> instance Num a => Num [a] where fromInteger n = Data.List.genericReplicate n 1 <interactive>:2:10: Warning: No explicit method or default declaration for `+'' In the instance declaration for `Num [a]'' <interactive>:2:10: Warning: No explicit method or default declaration for `*'' In the instance declaration for `Num [a]'' <interactive>:2:10: Warning: No explicit method or default declaration for `abs'' In the instance declaration for `Num [a]'' <interactive>:2:10: Warning: No explicit method or default declaration for `signum'' In the instance declaration for `Num [a]'' Prelude> 1 ++ 2 :: [Int] [1,1,1]


Porque alguien podría definir listas para ser tratadas como números:

instance Num a => Num [a] where (+) = zipWith (+) (*) = zipWith (*) (-) = zipWith (-) negate = map negate abs = map abs signum = map signum fromInteger x = [fromInteger x]

Entonces lo que escribiste funcionaría, ya que

1++2 == fromInteger 1++fromInteger 2 == [1]++[2]

(No es que este caso Num tenga mucho sentido ...)