在Haskell中的排序列表中创建新条目

时间:2014-12-18 14:56:34

标签: list sorting haskell

我实施了以下代码,以便在人员列表中创建一个新条目(包括姓名和出生日期)。列表按字母顺序排序,应保持此排序。如果名称相同,则日期定义排序。函数dateTurn可以转动日期并完美地运行。

type Lastname = String
type Firstname = String

dateTurn :: (Int, Int, Int) -> (Int, Int, Int)
dateTurn (a,b,c) = (c,b,a)

new :: ((Lastname,Firstname),(Int,Int,Int)) -> [((Lastname,Firstname),(Int,Int,Int))] -> [((Lastname,Firstname),(Int,Int,Int))]
new x [] = [x]
new x (y:ys)
    |(fst x)<(fst y) = x:(y:ys)
    |(fst x)>(fst y) = y: (new x ys)
    |(fst x)==(fst y) = if (dateTurn (snd x))<(dateTurn (snd y)) then y: (new x ys) else (x:y:ys)

编译脚本没有错误。如果我将一个人tupel添加到空列表中,它就可以工作。但是,如果我添加到非空列表。程序不会停止工作,我必须打断它才能停止工作。那么,如何解决这个问题?

1 个答案:

答案 0 :(得分:2)

由于您的操作是通用的,您应该抽象它

insertSorted :: Ord a => a -> [a] -> [a]
insertSorted x [] = [x]
insertSorted x (y:ys) | x <= y    = x: y: ys
                      | otherwise = y: insertSorted x ys

然后,将您的类型实例化为Ord

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

instance Ord Person where
   (Person a _) `compare` (Person b _) = a `compare` b

然后

print $ insertSorted (Person "Peter" 5) [ Person "John" 6
                                        , Person "Zorn" 3]