Sto giocando con il principiante Haskell e volevo scrivere una funzione media. Sembrava la cosa più semplice del mondo, giusto?I tipi Haskell frustrano una semplice funzione "media"
Errore.
Sembra che il sistema di tipi di Haskell impedisca al media di lavorare su un tipo numerico generico - Posso farlo funzionare su un elenco di Integrali, o su un elenco di Frazionali, ma non su entrambi.
voglio:
average :: (Num a, Fractional b) => [a] -> b
average xs = ...
ma posso ottenere solo:
averageInt :: (Integral a, Fractional b) => [a] -> b
averageInt xs = fromIntegral (sum xs)/fromIntegral (length xs)
o
averageFrac :: (Fractional a) => [a] -> a
averageFrac xs = sum xs/fromIntegral (length xs)
e il secondo sembra funzionare. Fino a quando non provo a passare una variabile.
*Main> averageFrac [1,2,3]
2.0
*Main> let x = [1,2,3]
*Main> :t x
x :: [Integer]
*Main> averageFrac x
<interactive>:1:0:
No instance for (Fractional Integer)
arising from a use of `averageFrac ' at <interactive>:1:0-8
Possible fix: add an instance declaration for (Fractional Integer)
In the expression: average x
In the definition of `it': it = averageFrac x
A quanto pare, Haskell è davvero pignolo per i suoi tipi. Ciò ha senso. Ma non quando potrebbero essere entrambi [Num]
Mi manca un'applicazione evidente di RealFrac?
C'è un modo per forzare gli Integrali in Frazionali che non soffocano quando riceve un input Frazionario?
C'è un modo per utilizzare Either
e either
per creare una sorta di funzione media polimorfa che possa funzionare su qualsiasi tipo di matrice numerica?
Il sistema di tipo Haskell a titolo definitivo vieta questa funzione da sempre esistente?
L'apprendimento di Haskell è come imparare il calcolo. È davvero complicato e basato su montagne di teoria e, a volte, il problema è così complesso che non conosco abbastanza bene per formulare correttamente la domanda, quindi qualsiasi intuizione sarà caldamente accettata.
(Inoltre, nota a piè di pagina: questo è basato su un problema di compiti a casa. Tutti concordano sul fatto che MediaFrac, sopra, ottiene punti pieni, ma ho un vago sospetto che esiste un modo per farlo funzionare su entrambi gli array Integral AND Fractional)
http: // StackOverflow.it/questions/1816993/haskell-dividendo-num –