我们可以放置函数来确定列表推导的条件。这是我试图实现的代码:
mQsort :: [String] -> [F.Record] -> [F.Record]
mQsort [] _ = []
mQsort c@(col:cond:cs) l@(x:xs) = (mQsort c small) ++ mid ++ (mQsort c large)
where
small = [y | y<-xs, (qGetStr col y) (qGetCond cond) (qGetStr col x)]
mid = mQsort cs [y | y<-l, (qGetStr col y) == (qGetStr col x)]
large = [y | y<-xs, (qGetStr col y) (qGetCond' cond) (qGetStr col x)]
qGetStr :: String -> F.Record -> String
qGetStr col r | U.isClub col = F.club r
| U.isMap col = F.mapName r
| U.isTown col = F.nearestTown r
| U.isTerrain col = F.terrain r
| U.isGrade col =F.mapGrade r
| U.isSW col = F.gridRefOfSWCorner r
| U.isNE col = F.gridRefOfNECorner r
| U.isCompleted col = F.expectedCompletionDate r
| U.isSize col = F.sizeSqKm r
| otherwise = ""
qGetCond "ascending" = (<)
qGetCond "decending" = (>)
qGetCond' "ascending" = (>)
qGetCond' "decending" = (<)
我收到一条错误,指出函数qGetStr应用于4个参数而不是2 此外,qGetCond - 这是返回运算符的正确语法。由于编译错误,我不得不将操作符放在括号中,但我感觉这是不正确的
答案 0 :(得分:8)
替换
small = [y | y<-xs, (qGetStr col y) (qGetCond cond) (qGetStr col x)]
与
small = [y | y<-xs, (qGetCond cond) (qGetStr col y) (qGetStr col x)]
同样适用于large
。
原因与您在qGetCond
中返回运算符的语法的原因相同。操作员真的只是一个功能。
foo < bar
与(<) foo bar
foo `fire` bar
与fire foo bar
所以你必须移动&#34;运算符&#34;到列表理解中的表达式的开头。 (n.b.这一般是正确的,特别是与列表理解无关。)
编辑:扩展Chris Kuklewicz的观点:
反引号仅适用于单个标识符。因此foo `fire` bar
是有效的语法,但更复杂的内容如foo `fire forcefully` bar
或foo `(fire forcefully)` bar
是语法错误。
括号轮操作符更灵活。这些表达式都评估为相同的值:
foo < bar
(<) foo bar
(foo <) bar
(< bar) foo
最后两个表单称为运算符部分。它们在将函数传递给另一个函数时很有用,例如map (+1) listOfIntegers
。语法有几个细微之处:
(quux foo <) -- function calls are fine
(baz + foo <) -- syntax error because of the extra operator...
((baz + foo) <) -- ...but this is ok
(-3) -- `-` is a special case: this is a numeric literal,
-- not a function that subtracts three
(subtract 3) -- is a function that subtracts three