#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
напрямую.