Я новичок в haskell. Попытка создать программу, которая позволяет вам вводить строку, а затем манипулировать ею с помощью различных команд.
Я объявил новый тип TextEdit, который хочу сохранить: -Текст слева от курсора (l) -Текст справа от курсора (r) -Текст "выбран" курсором (c) -и буфер обмена для копирования / вырезания / вставки (ов)
data TextEdit l r c s = TextEdit { left :: l, right :: r, cursor :: c, select :: s }
или же
data TextEdit l r c s = TextEdit { left :: [Char], right :: [Char], cursor :: [Char], select :: [Char]}
Остальная часть моего кода пока выглядит так:
main = do
putStrLn "-----Text Editor-----"
putStrLn "Please enter your text"
tInput <- getLine
let tI = TextEdit tInput "|" "" ""
putStrLn "\n\n"
putStrLn tInput
moveCursorLeft :: TextEdit -> TextEdit
moveCursorLeft (TextEdit(l, r, c, s)) = (TextEdit(l, r, c, s))
Пользователь будет вызывать moveCursorLeft tI для перемещения курсора.
Это ошибка, которую я получаю, когда пытаюсь запустить ее
TextEditor.hs:20:31: error:
* Expecting four more arguments to `TextEdit'
Expected a type, but `TextEdit' has kind `* -> * -> * -> * -> *'
* In the type signature: moveCursorLeft :: TextEdit -> TextEdit
|
20 | moveCursorLeft :: TextEdit -> TextEdit
| ^^^^^^^^
Спасибо за любую помощь, ребята :) Очень признателен
Гриша, я добавил это в свой код, и теперь это дает другую ошибку. TextEditor.hs: 21: 17: ошибка: * Конструктор TextEdit' should have 4 arguments, but has been given 1 * In the pattern: TextEdit (l, r, c, s) In an equation for
moveCursorLeft ': moveCursorLeft (TextEdit (l, r, c, s)) = (TextEdit (l, r, c, s)) | 21 | moveCursorLeft (TextEdit (l, r, c, s)) = (TextEdit (l, r, c, s)) | ^^^^^^^^^^^^^^^^^^^
l r c s
после вашего TextEdit - это аргументы тип. Если вы хотите, чтобы все они были [Char]
, просто оставьте их отключенными. Кроме того, вы неправильно строите свой TextEdit - конструкторы - это просто функции, TextEdit (l,r,c,s)
должен быть TextEdit l r c s
data TextEdit l r c s = TextEdit { left :: l, right :: r
, cursor :: c, select :: s }
Итак, TextEdit
- это конструктор типа, который принимает 4 аргумента типа, например TextEdit String String String String
будет допустимым типом. У вас также есть конструктор данных с таким же именем, TextEdit "a" "b" "c" "d"
будет допустимым значением типа TextEdit String String String String
.
data TextEdit l r c s = TextEdit { left :: [Char], right :: [Char]
, cursor :: [Char], select :: [Char]}
Это несколько другое и, вероятно, не то, что вам нужно. Здесь TextEdit
по-прежнему является конструктором типа, но аргументы не отображаются справа - они фантомны. Вместо этого, как насчет того, чтобы использовать:
data TextEdit = TextEdit { left :: [Char], right :: [Char]
, cursor :: [Char], select :: [Char]}
В дальнейшем мы будем использовать это определение. Теперь TextEdit
НЕ является конструктор типа, а просто тип.
moveCursorLeft :: TextEdit -> TextEdit
moveCursorLeft (TextEdit(l, r, c, s)) = (TextEdit(l, r, c, s))
Ах нет. Вы правильно использовали TextEdit
в программе main
, но, кажется, забыли то, что вы узнали. TextEdit (l,r,c,s)
говорит, что функция редактирования текста принимает один аргумент, который представляет собой набор из 4 значений. Однако, глядя на объявление данных, мы знаем, что TextEdit
принимает 4 аргумента, и все они [Char]
, а не кортежи. Так что используйте TextEdit l r c s
. То же самое и с определением функции:
moveCursorLeft :: TextEdit -> TextEdit
moveCursorLeft (TextEdit l r c s) = TextEdit l r c s
Повторюсь: (a,b,c,d)
- это одно значение - кортеж. F (a,b,c,d)
- это некий конструктор F
, примененный к этому единственному значению. F a b c d
- это конструктор F
, применяемый к четырем значениям. Приложение-функция использует пробелы, а не скобки с запятыми - отбросьте синтаксис C.
Textedit
ожидает четыре аргумента типа, чтобы стать взрослым типом, о котором вы можете рассуждать, то естьmoveCursorLeft :: TextEdit String String String String -> TextEdit String String String String