matt
matt

Reputation: 2039

Haskell: Sort Vector of custom Datatypes

How do I sort a Vector of custom data types using sortBy from Data.Vector.Algorithms ie:

data Person = Person 
  { name :: String
  , age  :: Int
  } deriving (Show, Eq)

p1,p2,p3 :: Person
p1 = Person "Alice"   30
p2 = Person "Bob"     20
p3 = Person "Charles" 10

personVec :: Vector Person
personVec = fromList [p2,p1,p3]

I would like to do something like:

sortedByName :: Vector Person
sortedByName = modify (sortBy (comparing name)) personVec

sirtedByAage :: Vector Person
sortedByAge  = modify (sortBy (comparing age)) personVec

but don't know what to put as the argument to sortBy

Upvotes: 0

Views: 739

Answers (1)

Thomas M. DuBuisson
Thomas M. DuBuisson

Reputation: 64740

Present the problem

Please include an MCVE including imports, pragma, the code, and errors. Ex:

{-# LANGUAGE OverloadedLists #-}
import Data.Vector
import Data.Ord
import Data.Vector.Algorithms.Intro

data Person = Person.
  { name :: String
  , age  :: Int
  } deriving (Show, Eq)

p1,p2,p3 :: Person
p1 = Person "Alice"   30
p2 = Person "Bob"     20
p3 = Person "Charles" 10

personVec :: Vector Person
personVec = fromList [p2,p1,p3]

sortedByName :: Vector Person -> Vector Person
sortedByName = modify sortBy (comparing name) personVec

sortedByAge :: Vector Person -> Vector Person
sortedByAge  = modify sortBy (comparing age) personVec

When loaded via ghci-8.4.3 $file, produces errors including this last one of:

so.hs:23:31: error:
    • Couldn't match expected type ‘Vector a1’
                  with actual type ‘Person -> Person -> Ordering’
    • Probable cause: ‘comparing’ is applied to too few arguments
      In the second argument of ‘modify’, namely ‘(comparing age)’
      In the expression: modify sortBy (comparing age) personVec
      In an equation for ‘sortedByAge’:
          sortedByAge = modify sortBy (comparing age) personVec
   |
23 | sortedByAge  = modify sortBy (comparing age) personVec
   |                               ^^^^^^^^^^^^^
Failed, no modules loaded.

Parens For Args

The modify function takes 2 arguments but you are passing three due to lack of parenthesis:

sortedByAge = modify (sortBy (comparing age)) personVec

Types: Is this a vector or a function?

Your sortedByAge variable is named to imply it is a vector but the type you provide shows it is a function that computes a vector. Let's change that type:

sortedByAge :: Vector Person

Same goes for sortedByName.

Result

*Main> sortedByName
[Person {name = "Alice", age = 30},Person {name = "Bob", age = 20},Person {name = "Charles", age = 10}]
*Main> sortedByAge
[Person {name = "Charles", age = 10},Person {name = "Bob", age = 20},Person {name = "Alice", age = 30}]

Upvotes: 3

Related Questions