Well, the problem is that you're using ordering comparisons, such as <=
, on two Account
values, which would require Account
to be an instance of Ord
. Now, Account
is a synonym for a four-element tuple, which are defined to be instances of Ord
when all the types in the tuple are. Accountno
, Name
, and Accountamount
are all synonyms for types with Ord
instances, but Accounttype
is not.
You could make it possible to sort Account
values directly by making Accounttype
an instance of Ord
, which you can do by simply adding it to the deriving
clause.
However, if you want to specifically sort only by the account number, not the other elements of the tuple, you'll need to do something differently. One option would be to make Account
a data type with a custom Ord
instance:
data Account = Account Accountno Name Accounttype Accountamount deriving (Eq, Show, Read)
instance Ord Account where
(...)
Then you can define the ordering however you like.
Alternatively, you can leave it as is and instead only compare the element you want instead of the entire Account
value, using something like this:
accountNo :: Account -> Accountno
accountNo (n,_,_,_) = n
...and then doing the comparison with something like smallerSorted = sortByID [x | x <- ls, accountNo x <= accountNo l]
. The standard libraries also include a function on
for this purpose, but it would awkward to use in this case.
A few other remarks, which are less relevant to your question, on the general subject of Haskell code:
Defining Account
as a data type, probably using the record syntax, would be nicer than using a type synonym here. Large tuples can be awkward to work with.
Accountno
and Accountamount
should probably be different types as well, to avoid mixing them with other Int
s: the first because doing arithmetic on account numbers makes little sense, the latter in part because (I'm guessing) you're implicitly using fixed point arithmetic, such that 100 actually means 1.00, and in general just to avoid confusion.
In fact, Int
is probably a bad choice for Accountamount
anyway: Why not something from Data.Fixed
, Ratio Integer
, or a base-10-safe floating point type (although there isn't one in the standard libraries, unfortunately).
The standard libraries of course include sorting functions already--I'm assuming the reimplementation is for learning purposes, but in practice it could all be replaced by something like sortBy (compare `on` accountNo)
.