Mentre è possibile fare tale sovraccarico in Haskell, non è considerato idiomatica, e sarà probabilmente portare a errori di confusione in seguito. Invece, si dovrebbe semplicemente definire le funzioni che costruiscono i dati:
point :: Rectangle
point = Rectangle 0 0
line :: Length -> Rectangle
line l = Rectangle l 0
square :: Int -> Rectangle
square a = Rectangle a a
Questo permette di dare nomi chiare che descrivono le semantica di ogni sovraccarico, piuttosto che basarsi su numero e sul tipo di argomenti dato a disambiguare cui si significare.
Tuttavia, se si vuole scrivere la versione di overload, lo si può fare facilmente con typeclasses:
class MakeRectangle a where
rectangle :: a
instance MakeRectangle Rectangle where
rectangle = Rectangle 0 0
instance MakeRectangle (Length -> Rectangle) where
rectangle l = Rectangle l 0
instance MakeRectangle (Length -> Width -> Rectangle) where
rectangle = Rectangle
Avrete bisogno {-# LANGUAGE FlexibleInstances #-}
nella parte superiore del file per compilare questo. Un trucco come questo è usato dalla libreria standard Text.Printf
, ma non lo considererei un esempio particolarmente valido di sovraccarico in Haskell; c'è quasi sempre una struttura per il tipo di valore sovraccarico, mentre qui la sua intera struttura è dettata dall'istanza, che può interferire con l'inferenza di tipo; non solo, ma non ci sono leggi ragionevoli che governano le istanze (anzi, il tipo è troppo generico per consentirne).
Ma se si vuole davvero farlo, è possibile, e anche se di solito è una cattiva idea, a volte (come nel caso di printf
) è l'unico modo per realizzare l'interfaccia che si desidera.
di provare questo in GHCi, è necessario specificare i tipi che si sta utilizzando in modo esplicito, altrimenti non sarà in grado di risolvere i casi:
GHCi> rectangle :: Rectangle
Rectangle 0 0
GHCi> rectangle (1 :: Length) :: Rectangle
Rectangle 1 0
GHCi> rectangle (1 :: Length) (2 :: Width) :: Rectangle
Rectangle 1 2
Non mi preoccuperei di provare a modellare haskell dopo C++; porterà solo un sacco di dolore. Inoltre, perché il tuo secondo costruttore di rettangoli è una linea? Penso che un'implementazione più ragionevole sarebbe quella di default a (1, 1), e se ne ottieni una int, passa (x, x), per formare un quadrato. – alternative
Hai mai sentito l'elenco di inizializzazione del costruttore? –
@VladLazarenko: hai mai sentito parlare di persone che stanno ancora imparando? (Suggerimento: sei tra loro, tutti lo sono) –