¿Cómo proporcionar declaraciones de tipo explícitas para funciones cuando se usa GHCi?


82

¿Cómo puedo definir el equivalente de esta función (tomada de learnyouahaskell ) dentro de GHCi?

import Data.List  

numUniques :: (Eq a) => [a] -> Int  
numUniques = length . nub  

Sin la declaración de tipo, GHCi acepta la definición de la función, pero termina con un tipo inútil:

Prelude Data.List> import Data.List 
Prelude Data.List> let numUniques' = length . nub
Prelude Data.List> :t numUniques'
numUniques' :: [()] -> Int

La función resultante solo acepta una lista de unidades como parámetro.

¿Hay alguna forma de proporcionar declaraciones de tipo en GHCi? ¿O hay otra forma de definir funciones como estas que no requieren declaraciones de tipo?

No vi pistas obvias en la guía de GHCi y experimenté con expresiones como las siguientes (en vano):

> let numUniques' = ((length . nub) :: (Eq a) => [a] -> Int)
> :t numUniques'
numUniques' :: [()] -> Int

Respuestas:


101

¿Hay alguna forma de proporcionar declaraciones de tipo en GHCi?

let numUniques' :: (Eq a) => [a] -> Int; numUniques' = length . nub

¿O hay otra forma de definir funciones como estas que no requieren declaraciones de tipo?

Si desactiva la restricción de monomorfismo con -XNoMonomorphismRestriction, inferirá el tipo correcto.


3
Todavía no estoy allí con el monomorfismo, pero en general esta respuesta me indicó el uso de punto y coma para agrupar definiciones en GHCi: los tutoriales están escritos como en un archivo .hs, lo que da muchos problemas diferentes cuando se prueban en GHCi (las funciones carecen de enlace, etc. .).
Tomasz Gandor

Vale la pena señalar que -XNoMonomorphismRestrictionestá habilitado de forma predeterminada para GHCi desde 7.8.1: downloads.haskell.org/~ghc/latest/docs/html/users_guide/…
N. Shead

13

Tenga en cuenta que también puede evitar la restricción de monomorfismo simplemente agregando "puntos" (es decir, variables explícitas) de nuevo a su expresión. Entonces esto también da el tipo correcto:

deje numUniques x = longitud. nudo $ x


1
Gracias, es bueno saberlo.
Mattbh

Esto se conoce como expansión eta
Bladt

3

La Guía del usuario de GHC muestra dos formas adicionales de lograrlo. Esta subsección presenta la construcción :{... :}, que se puede utilizar de la siguiente manera:

> :{
| numUniques :: (Eq a) => [a] -> Int
| numUniques = length . nub
| :}

Alternativamente, puede habilitar el modo multilínea :

> :set +m
> let
| numUniques :: (Eq a) => [a] -> Int
| numUniques = length . nub
| 
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.