2012-01-11 9 views
6

¿Es posible hacer lo siguiente:¿Es posible una declaración de tipo de ámbito?

foo = bar 
    where 
     type A = (Some, Huge, Type, Sig) 

     meh :: A -> (A, A) -> A 

que sólo tendrá que utilizar este tipo de encargo dentro de la cláusula where, por lo que no tiene sentido para definir globalmente.

+0

Supongo que esto es suponiendo que 'meh' no es polimórfico? –

Respuesta

8

Esto no es posible. ¿Por qué no simplemente definirlo arriba de la función? No tiene que exportarlo desde el módulo (solo use una lista de exportación explícita).

Por cierto, si realmente tiene un tipo tan grande, es probable que sea una señal de que debe factorizarlo en partes más pequeñas, especialmente si tiene muchas tuplas como sugiere su ejemplo; los tipos de datos serían más apropiados.

8

En realidad, hay uno, un poco ridícula, camino a la aproximación de esto:

{-# LANGUAGE TypeFamilies #-} 
{-# LANGUAGE ScopedTypeVariables #-} 

foo :: forall abbrv. (abbrv ~ (Some, Huge, Type, Sig)) 
    => abbrv -> abbrv 
foo x = meh x (x, x) 
    where meh :: abbrv -> (abbrv, abbrv) -> abbrv 
     meh x y = {- ... -} 

Realmente no puedo recomendar que permite dos extensiones del lenguaje por el simple hecho de abreviar tipos de firmas, aunque si ya está usándolos (o GADTs en lugar de escribir familias) Supongo que realmente no duele nada.

Tonterías aparte, debería considerar refaccionar sus tipos en casos como este, como sugiere el autor.

+1

¡Muy lindo! ¿Las variables de tipo de ámbito realmente se necesitan? (Parece que el tipo de igualdad es el bit realmente inteligente, y que podría moverse al tipo de 'meh'.) –

+0

Olvidó' RankNTypes'. – ehird

+0

@DanielWagner: solo se requiere la restricción de igualdad para el truco de abreviatura, sí. Pero la pregunta era específicamente sobre un tipo * con alcance *, por lo que no extenderlo a la cláusula 'where' hubiera sido insatisfactorio. :] –

Cuestiones relacionadas