I am trying to use generic programming in Haskell and need to sort an array of numbers but for some reason when I run the code, I receive an error stating "No instance for (Fractional Nums) In the expression: 645.41...." Every time I look at my code, I think it makes sense, but I'm not sure why it does not work...
import Data.List (sortBy)
import Data.Ord (comparing)
data Nums = Nums {numbers::Double} deriving(Ord, Eq, Show)
sortNums :: [Nums] -> [Nums]
sortNums = sortBy(comparing numbers)
arr = [645.41, 37.59, 76.41, 5.31, 1.11, 1.10, 23.46, 635.47, 467.83, 62.25]
main:: IO ()
main =
do
print(sortNums arr)
I apologize if this code looks messy or does not make sense, I am new to Haskell....
CodePudding user response:
Unless you have a good reason that's not obvious from the question, you should probably just delete Nums
entirely.
import Data.List (sort)
arr :: [Double]
arr = [645.41, 37.59, 76.41, 5.31, 1.11, 1.10, 23.46, 635.47, 467.83, 62.25]
main :: IO ()
main = print (sort arr)
CodePudding user response:
The problem here is that arr
is an array of Double
s, but you are calling sortNums
on it, which requires an array of Nums
. While these are effectively "the same" type, Haskell doesn't do any automatic conversions for you. If you replace print(sortNums arr)
with print (sortNums (map Nums arr))
- to ensure the list you're sorting has each member a Nums
value - then this works as intended.
(The error message you received here is unfortunately rather confusing and unhelpful, but derives from the fact that literal floating-point values like 645.41
can represent a value of any type that's an instance of the Fractional
typeclass. GHC sees you're trying to apply sortNums
to the list, and that this needs a list of Nums
, so it tries to make the values in the list of type Nums
- which it can do, but only if there is a Fractional
instance, which is why you get that specific error message. Don't worry too much about this - I'm just trying to explain why you get this particular error rather than one which would be more helpful like "couldn't match type [Double]
with expected type [Nums]
")