按值(a,b)的差值对Int对列表进行排序

时间:2018-05-28 06:34:28

标签: haskell tuples list-comprehension quicksort

如何按价值list的升序排序Int |first - second|ab :: (Int, Int) -> Int ab (x, y) = if x - y >= 0 then (x - y) else (x - y) * (-1) 对?

为了计算差异,我写了这段代码:

quicksort

我想对我得到的值使用sort :: [(Int,Int)] -> [(Int,Int)] sort [] = [] sort (x:xs) = sort smallerOrEqual ++ [x] ++ sort larger where smallerOrEqual = [a | a <- xs, a <= x] larger = [a | a <- xs, a > x]

ab

问题是如何将the函数构建到com.google.api.services.bigquery.model.TableReference table = new TableReference() .setProjectId(projectID) .setDatasetId(DatasetID) .setTableId(tablename); rows.apply("write to BigQuery", BigQueryIO .writeTableRows() .withSchema(schema) .to(table) .withWriteDisposition(WriteDisposition.WRITE_TRUNCATE) .withCreateDisposition(CreateDisposition.CREATE_IF_NEEDED)); 排序函数中?我尝试了几种方法,但总是遇到编译器错误。

2 个答案:

答案 0 :(得分:4)

让我们只使用标准库函数!

首先,有一个名为sortBy的排序函数的通用版本(我将使用GHCi的辉煌:t命令显示相关函数的类型):

ghci> import Data.List
ghci> :t sortBy
sortBy :: (a -> a -> Ordering) -> [a] -> [a]

sortBy的第一个参数表明,为了比较元素,我们需要一个排序谓词 - 一个函数,它接受列表中的两个元素并告诉第一个元素是否更大。在许多情况下,包括您的,您不必自己定义这样的功能。相反,您可以使用“度量”函数,列表元素的重要性。例如。您有一个列表(x,y)的元素,其度量为|x-y| - 这正是您的ab函数,但请记住,我们希望通过标准函数定义它。

目前,我们有两个任务:1)定义类型(Int, Int) -> Int的度量函数; 2)学习如何将其转换为排序谓词。我说后者是微不足道的,因为它可以通过标准函数comparing完成:

ghci> import Data.Ord
ghci> :t comparing
comparing :: Ord a => (b -> a) -> b -> b -> Ordering

所以我建议comparing absortBy的第一个参数完全匹配。不要让我们转向另一项任务:通过标准函数定义ab

考虑-函数的类型:

ghci> :t (-)
(-) :: Num a => a -> a -> a

如果用Int代替a(¹),你几乎可以得到你想要的类型,即Int -> Int -> Int。在这里,我们经常将一个函数从两个参数((-))转换为一个作用于对的函数。幸运的是,有一个标准的功能,即uncurry

ghci> :t uncurry (-)
uncurry (-) :: Num c => (c, c) -> c

这就是我们需要的!现在我们只需要使用计算abs的{​​{1}}函数来管道它,我们就是好的。我们将函数组成|·|的方法。得到的解决方案就是这个:

.

您可以在GHCi中尝试一下,假设您将其保存在import Data.List (sortBy) import Data.Ord (comparing) sortAbsPairs :: [(Int,Int)] -> [(Int,Int)] sortAbsPairs = sortBy (comparing $ abs . uncurry (-))

sort.hs

(¹)你实际上可以要求GHCi通过设置一个名为ghci>:l sort.hs Ok, one module loaded. ghci> sortAbsPairs [(8,20), (5, 10), (1,2)] [(1, 2), (5, 10), (8, 20)] 的语言扩展来替换类型的函数类型参数:

TypeApplications

答案 1 :(得分:3)

虽然sortBy众所周知,但大多数都伴随着comparing。您可以改用sortOnsortOn的优点是它使用Schwartzian变换,即它只为每个元素计算一次差值。

--Prelude Data.List> :t sortOn
--sortOn :: Ord b => (a -> b) -> [a] -> [a]

import Data.List(sortOn)
sort = sortOn (abs . uncurry (-))

但是如果你真的想使用你的原始排序,模式匹配对:

sort ((x,x'):xs) = [ (a,a') | (a,a') <- xs, -- ... your homework here

我稍后会延长作业部分以使其成为完整的答案。