2012-01-11 7 views
6

E 'possibile effettuare le seguenti operazioni:È possibile un'istruzione di tipo scoped?

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

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

ho solo bisogno di utilizzare questo tipo personalizzato all'interno della clausola in cui, in modo che non ha senso per definire globalmente.

+0

Suppongo che questo presuma che 'meh' non sia polimorfico? –

risposta

8

Questo non è possibile. Perché non basta definirlo sopra la funzione? Non è necessario esportarlo dal modulo (basta usare un elenco di esportazione esplicito).

A proposito, se davvero hai un tipo così grande, probabilmente è un segnale che devi calcolarlo in parti più piccole, specialmente se hai un sacco di tuple come suggerisce il tuo esempio; i tipi di dati sarebbero più appropriati.

8

In realtà, c'è uno, un po 'ridicolo, modo per approssimare questo:

{-# 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 = {- ... -} 

non posso davvero consigliare consentendo due estensioni del linguaggio solo per il gusto di abbreviare i tipi di firme, anche se siete già usandoli (o GADT invece di famiglie di tipi) suppongo che non faccia del male a nulla.

Sciocchezze a parte, dovresti prendere in considerazione il refactoring dei tuoi tipi in casi come questo, come suggerisce l'eird.

+1

Molto carino! Le variabili di tipo scoped sono davvero necessarie? (Sembra che l'uguaglianza di tipo sia il bit davvero intelligente, e che potrebbe essere spostato nel tipo di 'meh'.) –

+0

Hai dimenticato' RankNTypes'. – ehird

+0

@DanielWagner: solo il vincolo di uguaglianza è richiesto per il trucco dell'abbreviazione, sì. Ma la domanda riguardava specificamente un tipo * scoped *, quindi non estenderlo alla clausola 'where' sarebbe stata insoddisfacente. :] –

Problemi correlati