Используя функции в списках, Haskell? - PullRequest
1 голос
/ 10 января 2012

Можем ли мы поставить функции, чтобы определить условие для наших списочных представлений. Вот мой код, который я пытаюсь реализовать:

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 - это правильный синтаксис для возврата оператора. Мне пришлось поместить оператор в скобки из-за ошибки компиляции, но у меня такое ощущение, что это неправильно

1 Ответ

8 голосов
/ 10 января 2012

Заменить

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

Таким образом, вы должны переместить «оператор» в начало выражения в вашем понимании списка.(NB это верно в целом и не имеет ничего общего с пониманием списков в частности.)

Редактировать: чтобы расширить точку зрения Криса Куклевича:

  • Обратные помехи работают толькоединственный идентификатор.Так что 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
    
...