2013-02-07 14 views
13

Ho questocome scrivere una classe derivabile?

data Something = Something Integer deriving (MyClass, Show) 

class MyClass a where 
    hello :: MyClass a => a -> a 

instance MyClass Integer where 
    hello i = i + 1 

main = print . hello $ Something 3 

ma MyClass non è derivabile. Perché?

+6

Non è necessaria la parte 'MyClass a =>' della firma del tipo per 'ciao'; è implicito dal fatto che 'a' viene reso noto da una dichiarazione di classe del modulo' classe MyClass a dove ... '. –

+0

Dai un'occhiata alla [guida degli utenti di GHC sulla derivazione] (https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/glasgow_exts.html#extensions-to-the-derder-mechanism). –

risposta

13

GHC non è in grado di ricavare magicamente istanze per tipi di dati arbitrari. Tuttavia, lo può utilizzare il fatto che le dichiarazioni newtype creano un nuovo nome per lo stesso tipo sottostante per derivare le istanze per quelli che utilizzano l'estensione GeneralizedNewtypeDeriving. Quindi, si potrebbe fare qualcosa di simile:

{-# LANGUAGE GeneralizedNewtypeDeriving #-} 

newtype Something = Something Integer deriving (MyClass, Show) 

class MyClass a where 
    hello :: MyClass a => a -> a 

instance MyClass Integer where 
    hello i = i + 1 

main = print . hello $ Something 3 

La ragione GHC non può derivare la nuova istanza è che non sa che cosa l'istanza dovrebbe essere. Anche se il tuo tipo di dati ha solo un campo, potrebbe non essere lo stesso come quel campo. La possibilità di derivare istanze per newtype s è conveniente, poiché esse sono solitamente utilizzate per fornire comportamenti diversi per determinati tipi di caratteri o come metodo per utilizzare il sistema di tipi per separare elementi che hanno lo stesso tipo ma usi diversi nel codice.

+2

Il 'newtype' derivante è conviente ma non sicuro con la sua attuale implementazione. Dico solo l'uso nelle prime versioni del tuo codice. Il nuovo framework 'default'/generic è più generale e sicuro (ma anche clunkier), quindi usalo quando è possibile. –

+0

@PhilipJF Questo è bello sapere. – sabauma

+0

@PhilipJF cosa non è sicuro dell'attuale implementazione di newtype derivante? –

13

Si consiglia di dare un'occhiata al GHC documentation on Generic Programming.
È necessario creare una classe che possa funzionare su una rappresentazione generica di tipi arbitrari. Non penso che l'esempio specifico che hai dato sia ragionevole per una classe derivabile.

+2

+1 Sono contento che qualcuno lo abbia presentato come risposta a questa domanda. Ti piace esapere in un esempio di uno in cui è ragionevole? – AndrewC

+0

@AndrewC sfortunatamente non lo capisco abbastanza bene da espandermi così lontano. Se ti senti libero di modificare la domanda. – asm

+0

ecco un esempio di una classe generica "Default" (un tipo è predefinito al suo primo costrutto): http://pastebin.com/amgQRvFD (sto imparando da solo la programmazione generica, non so se questo è il migliore modo) –

Problemi correlati