У меня есть объявление функции e6. Мне нужно заменить undefined каким-то кодом и заставить его работать.

e6 :: Int -> Int -> Int
e6 = undefined

Я знаю например

add :: Int -> Int -> Int
add a b = a + b

Он принимает параметры a и b, а затем возвращает a + b. Но как я могу написать функцию без аргументов. Я попытался

e6 :: Int -> Int -> Int
e6 = 2 + 3

И он сказал:

Нет экземпляра для (Num (Int -> Int -> Int)), возникающего в результате использования '+'

3
H. Dong 16 Сен 2018 в 02:56

2 ответа

Лучший ответ

Непонятно, какое исправление нужно делать, потому что мне не совсем понятно, чего именно вы хотите. Вот несколько возможных интерпретаций того, что вы хотите.

  • Вы хотите, чтобы e6 был эквивалентен константе 5, вычисляемой путем вычисления 2+3. Поскольку это не функция, вам не следует использовать в ее сигнатуре тип функции.

    e6 :: Int
    e6 = 2 + 3
    
  • Вы хотите, чтобы функция e6 была такой же, как add, но всегда возвращала 2+3 вместо a+b, то есть игнорировала ее аргументы, даже если она все еще есть они. Тогда подпись типа в порядке, но вам нужно явно игнорировать аргументы.

    e6 :: Int -> Int -> Int
    e6 _ _ = 2 + 3
    -- OR
    e6 a b = 2 + 3
    
  • Вы хотите, чтобы e6 во всех отношениях был похож на add, но вы не хотите явно указывать его аргументы при определении e6. Затем, если вы не даете аргументы e6, вы также не можете давать аргументы +. Так:

     e6 :: Int -> Int -> Int
     e6 = (+)
    

    (+) - специальный синтаксис для преобразования инфиксного оператора в префиксную функцию; грубо говоря, \a b -> (+) a b и \a b -> a + b ведут себя одинаково.

10
Daniel Wagner 16 Сен 2018 в 12:56

Вы спрашиваете, как написать функцию в стиле без точек?

Если это так, вы можете написать функцию сложения как:

e6 = (+)

В этом простом примере e6 просто становится псевдонимом для оператора +. В Haskell операторы - это просто функции со специальными именами, и когда вы хотите использовать их как функции вместо операторов, вы заключаете их в скобки, как указано выше. Функция (+) (т.е. оператор +) уже является функцией, которая принимает два аргумента и возвращает значение.

Вот пример взаимодействия с ним GHCi:

Prelude> :t e6
e6 :: Num a => a -> a -> a
Prelude> e6 1 3
4
Prelude> e6 42 1337
1379

Выведенный тип - Num a => a -> a -> a, но он также совместим с Int -> Int -> Int, поэтому, если вы хотите ограничить тип этим, вы можете объявить функцию с этим более ограниченным типом. Однако нет особой причины для этого, поскольку общая версия также отлично работает с Int, как показывает сеанс GHCi.

4
Mark Seemann 16 Сен 2018 в 00:16