Haskell: не компилируется с пользовательским типом данных

Я новичок в 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
   |                               ^^^^^^^^

Спасибо за любую помощь, ребята :) Очень признателен

Textedit ожидает четыре аргумента типа, чтобы стать взрослым типом, о котором вы можете рассуждать, то есть moveCursorLeft :: TextEdit String String String String -> TextEdit String String String String
Grisha 02.05.2018 16:30

Гриша, я добавил это в свой код, и теперь это дает другую ошибку. 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)) | ^^^^^^^^^^^^^^^^^^^

BasicBooties 02.05.2018 16:35

l r c s после вашего TextEdit - это аргументы тип. Если вы хотите, чтобы все они были [Char], просто оставьте их отключенными. Кроме того, вы неправильно строите свой TextEdit - конструкторы - это просто функции, TextEdit (l,r,c,s) должен быть TextEdit l r c s

Cubic 02.05.2018 16:36
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
3
59
1

Ответы 1

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.

Другие вопросы по теме