Haskell: è possibile convertire un Num in un Float?

3

Devo essere in grado di convertire numeri generici (istanze di Num ) in Float . Ho cercato su Hoogle una funzione con la firma Num n => n -> Float , ma non sono riuscito a trovare nessuna di queste funzioni (anche se potrebbe essere possibile comporla). Ho anche esaminato il Num typeclass e non sembra che richieda delle istanze per fornire funzioni di conversione che potrebbero aiutarmi.

Perché devo fare questo? Ho creato un typeclass Moveable che definisce le operazioni per spostare una coordinata e gli consente di lavorare con qualsiasi istanza di Num , poiché l'unica cosa richiesta per spostare una coordinata è + , che è definita da Num . Il mio obiettivo finale era quello di usare questo con Gloss (una libreria grafica), ma sfortunatamente, Gloss usa solo Float s. Ciò significa che se sto memorizzando le coordinate come Num , alla fine dovrò convertirle quando tento di visualizzare un oggetto.

Preferisco non rendere il tipo di numero più specifico, quindi funzionerà con Gloss. Qualcuno ha qualche idea che potrebbe aiutare?

    
posta Carcigenicate 31.08.2015 - 18:25
fonte

2 risposte

6

Perché "memorizzi" i tuoi valori come Num invece di Float ? (Come li stai salvando? Num non è nemmeno un tipo quindi non puoi memorizzarli così ...)

Prelude> let y = 3.0::Float
Prelude> :t y
y :: Float
Prelude> let plus a b = a+b
Prelude> :t plus
plus :: Num a => a -> a -> a
Prelude> :t (plus y)
(plus y) :: Float -> Float
Prelude> plus y y
6.0
Prelude>

In conclusione: Usa solo Float . A meno che tu non abbia qualche ragione per non farlo?

Di norma, ricorda che Haskell ha pochissimo in termini di conversioni rese disponibili anche se puoi forzarle in vari modi se è davvero necessario. L'approccio idiomatico a queste cose è sempre:

Scopri come rendere disponibili al compilatore le informazioni sul tipo in modo che i tuoi tipi siano garantiti e non avrai bisogno di fare conversioni

    
risposta data 31.08.2015 - 18:46
fonte
1

Non puoi convertire arbitrariamente Num istanze in Float perché la classe Num è troppo generica per consentirlo. Ad esempio, il tipo Complex ha istanze Num . Cosa significherebbe "convertire" un numero complesso in un numero reale? Non penso che ci sia alcun senso accettato di ciò che significherebbe.

Guardando l'insieme confuso di classi numeriche di Haskell, penso di poter individuare questo modello: le funzioni di "conversione" sono generalmente fornite solo dove c'è qualcosa come un Injective mapping tra i set di numeri matematici rappresentati dai tipi. Ad esempio, per convertire un'istanza Integral in un numero reale o complesso hai fromIntegral :: (Integral a, Num b) -> a -> b . Ma non esiste una funzione di "conversione" da RealFrac istanze a tipi interi - devi dire esplicitamente se vuoi truncate , round , ceiling o floor .

I created a typeclass Moveable that defines operations to move a coordinate, and allowed it to work with any instance of Num, since the only thing required to move a coordinate is +, which is defined by Num.

Poiché Complex ha istanze Num , la tua scelta qui significa che hai ammesso nel tuo modello il concetto di spostamento delle coordinate per importi complessi. Ha senso nella tua applicazione? Mi sembra che tu debba fare una delle seguenti azioni:

  1. Scegli un tipo più ristretto per la tua classe Moveable ;
  2. Incorporare alcuni concetti di sistemi di coordinate e conversioni nella tua classe.
risposta data 25.11.2015 - 20:31
fonte

Leggi altre domande sui tag