2012-07-16 10 views
8

Novizio totale qui, in difficoltà.Haskell: come posso definire una classe di caratteri per gli insiemi?

Sto provando a definire una classe di caratteri per insiemi. In questo caso richiederebbe solo la definizione di "esiste". 'Esiste' prenderebbe un set e funzionerebbe su un elemento impostato e restituirà un valore booleano a . Come posso definirlo in Haskell?

È il seguente anche nella giusta direzione? Quindi non v'è la definizione del tipo di classe e un implementazione di set con la lista, per i quali 'esiste' restituisce vero per ora ..

-- Set.hs -- 

class Set a b where 

    exists :: a -> (b -> Bool) -> Bool 


-- ListSet.hs -- 

instance Set ListSet a where 

    exists a f = True 

-

(risultato: Troppi parametri per la classe `Set ')

risposta

13

È possibile farlo in questo modo, con estensioni sufficienti. Per lo meno, avrai bisogno di classi di tipi a parametri multipli. Tuttavia, sarà molto fastidioso da usare: sarà necessario specificare le firme di tipo esplicito dappertutto. Un modo per risolvere il problema è quello di introdurre una dipendenza funzionale (utilizzando un altro interno):

class Set a b | a -> b where 
    exists :: a -> (b -> Bool) -> Bool 

Questo dice che se si conosce il tipo di set, si conosce il tipo di elementi, anche. Tuttavia, c'è un modo più semplice che funziona senza estensioni:

class Set f where 
    exists :: f a -> (a -> Bool) -> Bool 

Qui, la classe di tipo spazia tipi superiori-kinded, che è un trucco e difficile da trovare con il proprio se non hai mai visto prima!

+1

Ovviamente, quest'ultimo richiede che il tipo di elemento sia l'ultimo parametro di tipo per il tipo set - qualcosa non sempre possibile, come se si volesse creare un'istanza per 'a -> Bool'. Le famiglie di tipi associati, d'altra parte, risolvevano ciò proprio bene. – Carl

+2

Grazie! Ho ottenuto il secondo modo di lavorare! Devo ammettere che non capisco cosa succede lì, ma spero che mi si riveli ... – tero

7

Daniel Wagner ha già dato una risposta perfetta su ciò che stai cercando di fare. Voglio solo aggiungere un punto sul tuo errore - Too many parameters for class 'Set'. Ciò significa che non hai abilitato l'estensione GHC corrispondente - MultiParamTypeClasses. È possibile farlo specificando speciale tipo di commento nella parte superiore del file di origine:

{-# LANGUAGE MultiParamTypeClasses #-} 
-- 
-- Your source code here 
-- 

allora si dovrebbe essere in grado di compilare il codice.

Un'altra funzione di Haskell menzionata nella risposta di Daniel richiede anche l'abilitazione di determinate estensioni, ovvero FunctionalDependencies (questa è la strana cosa di .. | a -> b .. all'interno della dichiarazione della classe di tipi). È possibile abilitare le estensioni multiple allo stesso tempo utilizzando una virgola, come questo:

{-# LANGUAGE MultiParamTypeClasses, FunctionalDependencies #-} 

commento di Carl menziona un altro interno, TypeFamilies, che potrebbe anche fornire mezzi per ciò che si sta cercando di fare (classe generica dei tipi di set o di altri tipo di collezioni). Puoi leggerlo qui: http://www.haskell.org/haskellwiki/Type_families.

+0

Sono riuscito a farlo anche con il metodo di dipendenza funzionale. Tuttavia, dovevo includere anche l'estensione "FlexibleInstances". – tero

Problemi correlati