it-swarm.com.ru

Многострочные команды в GHCi

У меня проблема с вводом многострочных команд в ghci.

Следующий двухстрочный код работает из файла:

addTwo :: Int -> Int -> Int
addTwo x y = x + y

Но когда я вхожу в GHCI, я получаю ошибки. 

Я также попытался поместить код внутри :{ ... :}, но они также не работают для этого примера, потому что это просто добавление строк в одну строку, что не должно иметь место.

Я использую WinGHCi, версия 2011.2.0.1

108
R71

Большую часть времени вы можете рассчитывать на вывод типа для вашей подписи. В вашем примере достаточно следующего:

Prelude> let addTwo x y = x + y

Если вы действительно хотите определение с сигнатурой типа или если ваше определение занимает несколько строк, вы можете сделать это в ghci:

Prelude> :{
Prelude| let addTwo :: Int -> Int -> Int
Prelude|     addTwo x y = x + y 
Prelude| :}
Prelude> addTwo 4 7
11

Обратите внимание, что вы также можете сжать это в одну строку:

Prelude> let addTwo :: Int -> Int -> Int ; addTwo x y = x + y

Вы можете узнать больше о взаимодействии с ghci в Интерактивная оценка в разделе Подсказка документации.

151
Nicolas Wu

Решите эту проблему, запустив GHCI и набрав :set +m:

Prelude> :set +m
Prelude> let addTwo :: Int -> Int -> Int
Prelude|     addTwo x y = x + y
Prelude| 
Prelude> addTwo 1 3
4

Boom.


Что происходит здесь (и я в основном говорю с you, человеком, который ищет помощь во время прохождения Learn You A Haskell ) того, что GHCI - это интерактивная среда, в которой вы меняетесь привязки имен функций на лету. Вы должны обернуть определения своих функций в блок let, чтобы Haskell знал, что вы собираетесь что-то определить. Материал :set +m является сокращением для многострочной конструкции :{code:}.

Пробелы также имеют большое значение в блоках, поэтому вы должны отступить от определения функции после определения типа на четыре пробела, чтобы учесть четыре пробела в let.

94
adrian

Используйте let:

Prelude> :{
Prelude| let addTwo :: Int -> Int -> Int
Prelude|     addTwo x y = x + y
Prelude| :}
Prelude> addTwo 2 3
5
13
Stefan Holdermans

Начиная с GHCI версии 8.0.1 , let больше не требуется для определения функций в REPL.

Так что это должно хорошо работать для вас:

λ: addTwo x y = x + y
λ: addTwo 1 2
3
λ: :t addTwo
addTwo :: Num a => a -> a -> a

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

λ: addTwo 2.0 1.0
3.0

Если вы должны предоставить свою собственную типизацию, вам, вероятно, нужно использовать let в сочетании с многострочным вводом (используйте :set +m для включения многострочного ввода в GHCI):

λ: let addTwo :: Int -> Int -> Int
 |     addTwo x y = x + y
 | 
λ: addTwo 1 2
3

Но вы получите ошибки, если попытаетесь передать что-либо, кроме Int, из-за вашей неполиморфной типизации:

λ: addTwo 2.0 1.0

<interactive>:34:8: error:
    • No instance for (Fractional Int) arising from the literal ‘2.0’
    • In the first argument of ‘addTwo’, namely ‘2.0’
      In the expression: addTwo 2.0 1.0
      In an equation for ‘it’: it = addTwo 2.0 1.0
0
Aaron Hall