#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)