如何按价值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));
排序函数中?我尝试了几种方法,但总是遇到编译器错误。
答案 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 ab
与sortBy
的第一个参数完全匹配。不要让我们转向另一项任务:通过标准函数定义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
。您可以改用sortOn
。 sortOn
的优点是它使用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
我稍后会延长作业部分以使其成为完整的答案。