[英]Haskell: Polymorphic functions explanation
所以我得到了这个
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中执行此操作。 关于如何启动此功能的任何线索都很好。 也许某种模式?
谢谢。
对问题的第一部分的部分答案:
在传递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...
函数之一传递给intCMP...
时,在类型intCMP...
期间发生的sort3
是(简而言之)编译器尝试将sort3
的第一个参数(a -> a -> Ordering)
sort3
(a -> a -> Ordering)
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
这里有一个提示:
您不是在编写多态函数(根据定义,该函数需要多个类型)。 首先写一个:
cmp :: Ord a => a -> a -> Ordering
cmp x y =
| x == y = EQ
| x < y = LT
| otherwise = GT
您将以这种方式编写上面的代码,该功能可以比较排序中的元素,而不必成为排序的一部分。 对列表进行排序本质上是递归的:至少在未定义长度的情况下。 为此,只需编写一个可以利用自定义比较的排序,尽管您可以编写其他类型的排序,但这是一种快速排序。
sort3 :: (Ord a) => [a] -> [a]
sort3 [] = []
sort3 (x:xs) =
let smallerSorted = filter (<=)
biggerSorted = filter(>)
in smallerSorted ++ [x] ++ biggerSorted
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.