所以我得到了这个
intCMP :: Int -> Int -> Ordering
intCMP a b | a == b = EQ
| a < b = LT
| otherwise = GT
intCMPRev :: Int -> Int -> Ordering
intCMPRev a b | a == b = EQ
| a < b = GT
| otherwise = LT
floatCMP :: Float -> Float -> Ordering
floatCMP a b | a == b = EQ
| a < b = LT
| otherwise = GT
我需要写这个函数
sort3 :: Ord a => (a -> a-> Ordering) -> [a] -> [a]
sort3 cmp xs =
通过比较,将对3个或更少的元素进行排序。没有递归。我想知道这是如何工作的传递说intCMP。你为什么要把它传递给sort函数?在排序和返回排序列表时它是否有用?我不确定如何在没有任何递归调用的情况下手动进行比较,所以我只是想更好地理解它。
我正在考虑进行3次比较,然后将元素移动到列表中的某个位置,但我真的不知道我怎么能在haskell中做到这一点。关于如何开始这个的任何线索都会很棒。也许是某种模式?
感谢。
答案 0 :(得分:3)
对问题第一部分的部分回答:
将intCMP
传递给sort3
可让您控制排序的完成方式。据推测,sort3 intCMP [7,3,6]
将返回[3,6,7]
,而sort3 intCMPRev [7,3,6]
将返回[7,6,3]
。你甚至可以制作自己奇怪的排序函数,比如首先是所有偶数,然后是所有奇数排序函数,如下所示:
intCMPWeird :: Int -> Int -> Ordering
intCMPWeird a b
| even a && even b = intCMP a b -- even numbers compare as usual
| odd a && odd b = intCMPRev a b -- odd numbers compare in reverse order
| even a && odd b = LT -- evens are all 'smaller' than odds
| odd a && even b = GT -- odds are all 'greater' than evens
使用此功能,sort3 intCMPWeird [7,3,6]
应该提供[6,7,3]
。
将intCMP...
函数之一传递给sort3
时,在类型检查期间会发生什么(简而言之),编译器首先尝试匹配sort3
的类型参数(a -> a -> Ordering)
使用提供的值(Int -> Int -> Ordering)
的类型,并通过使a
等于Int
成功完成此操作。然后需要检查Ord a
是否满足约束Int
,这有效!最后,编译器可以确定sort3 intCMP
的类型是[Int] -> [Int]
。同样,sort3 floatCMP
的类型为[Float] -> [Float]
。
我不能100%确定为什么Ord
约束的类型为sort3
,因为您可以从传入的比较函数中获取所需的信息 - 你确定你已经输入正确吗?
编辑:提示如何使用where子句来获得可读的定义,你仍然需要填写一些内容并添加更多的子句:
sort3 cmp [x,y,z]
| x <= y && somethingElse1 = listWithXyzInSomeOrder1
| x <= z && somethingElse2 = listWithXyzInSomeOrder2
where a <= b = cmp a b /= GT
答案 1 :(得分:2)
这是一个提示:
答案 2 :(得分:0)
你不是在编写多态函数(根据定义,它是一个需要多种类型的函数)。先写一个:
cmp :: Ord a => a -> a -> Ordering
cmp x y =
| x == y = EQ
| x < y = LT
| otherwise = GT
您将以上述方式编写比较排序中元素的功能,而不必是排序的一部分。对列表进行排序本质上是递归的:至少长度是未定义的。要实现这一点,只需编写一个可以使用自定义比较的排序,这里是quick sort,尽管您可以编写不同类型的排序。
sort3 :: (Ord a) => [a] -> [a]
sort3 [] = []
sort3 (x:xs) =
let smallerSorted = filter (<=)
biggerSorted = filter(>)
in smallerSorted ++ [x] ++ biggerSorted