Как передать not функцию, которая возвращает логическое значение в другой функции?

#haskell

#haskell

Вопрос:

Я хочу отменить функцию в предложении if другой функции, подобной приведенной ниже:

 isBig :: Integer -> Bool
isBig n = n > 9999

function :: Integer -> Integer
function n =
   if not isBig n then ... else ...
  

Это соответствует, когда это просто ‘if isBig n then else’, но я не уверен, почему это не работает для ‘not isBig’, когда я получаю эту ошибку:

* Не удалось сопоставить ожидаемый тип Bool' with actual type Integer -> Bool’

Заранее большое спасибо.

Ответ №1:

Вы хотите not (isBig n) . not isBig n пытается передать два аргумента not , оба isBig и n . isBig является Integer -> Bool , но Bool ожидается, отсюда и ошибка.

В общем случае применение функции в Haskell является левоассоциативным, что означает, что выражение, подобное этому:

 f 2 3 5
  

Анализируется следующим образом:

 (((f 2) 3) 5)
  

Аналогично, стрелки в типах функций являются ассоциативными с правом, поэтому, например, если бы у нас было это определение для f :

 f :: Int -> Int -> Int -> Int
f x y z = x * y   z
  

Эта подпись типа такая же, как:

 f :: Int -> (Int -> (Int -> Int))
  

Итак, это выглядит так, когда вы применяете больше аргументов:

    f         :: Int -> (Int -> (Int -> Int))
  (f 2)      ::        (Int -> (Int -> Int))
 ((f 2) 3)   ::                (Int -> Int)
(((f 2) 3) 5 ::                        Int

==

f       :: Int -> Int -> Int -> Int
f 2     ::        Int -> Int -> Int
f 2 3   ::               Int -> Int
f 2 3 5 ::                      Int
  

Когда вы применяете цепочку функций к аргументу, вы в конечном итоге получаете круглые скобки, связанные справа:

 f (g (h x))
  

В этом случае обычно используется $ оператор, который является правоассоциативным и имеет низкий приоритет, просто чтобы уменьшить вложенность скобок:

 f $ g $ h x
  

И вы можете сделать это в вашем случае: not $ isBig n

Вы также можете использовать композицию для выделения цепочки функций и применения ее к другим аргументам в другом месте:

 fgh = f . g . h

fgh x
==
(f . g . h) x
==
f (g (h x))
  
 isNotBig = not . isBig

isNotBig n
==
(not . isBig) n
==
not (isBig n)