Передача функции Ord в качестве параметра функции

#haskell

Вопрос:

Здравствуйте, в данный момент я изучаю Haskell, и мне было интересно, могу ли и как я передать функцию эквалайзера в качестве параметра другой функции, поскольку она работает с ( ), ( — ) и (*) (и я знаю, что передача функций в целом работает в haskell). Я хочу работать с оператором эквалайзера в моей функции панели в зависимости от того, меньше ли заголовок моего списка, равен или больше 0. Но так, как я сделал это в приведенном ниже фрагменте кода, я получаю ошибку компилятора. Извините, если я упускаю здесь что-то очевидное, я довольно новичок в хаскелле, ваша помощь и объяснения приветствуются.

 foo :: [x] -gt; [x] foo x  | head x lt; 0 = bar (lt;) x  | head x == 0 = bar (==) x  | head x gt; 0 = bar (gt;) x  bar :: (a -gt; a -gt; Bool) -gt; [x] -gt; [x] bar func x = ...  

Ответ №1:

Вам нужно добавить Ord ограничение bar , так как вы не можете использовать значения любого типа с (lt;) et al, только те, у Ord которых есть экземпляр. Вам также необходимо использовать a весь тип; использование x подразумевает, что тип передаваемого списка не зависит от Ord ограничения, которое не позволит вам использовать func элемент аргумента x .

 bar :: Ord a =gt; (a -gt; a -gt; Bool) -gt; [a] -gt; [a]  bar func x = ...  

Поскольку Eq это суперкласс Ord , вам не нужно указывать Eq явно; экземпляр Ord подразумевает экземпляр Eq .

Вам также нужно ограничение foo , так как вы используете lt; , == , и gt; в охранниках, а не только в качестве аргументов bar . Чтобы подчеркнуть исчерпываемость, попробуйте использовать compare вместо трех отдельных охранников

 foo :: Ord a =gt; [a] -gt; [a] foo x = let f = case compare (head x) 0 of  LT -gt; (lt;)  EQ -gt; (==)  GT -gt; (gt;)  in bar f x  

(И подумайте, что, если что-то нужно сделать с аргументом пустого списка, чтобы foo .)

Комментарии:

1. Большое вам спасибо за ваше объяснение 🙂

2. Я не понимаю, зачем bar нужны ограничения. Он передается a -gt; a -gt; Bool напрямую.