Для меня это похоже на вопрос о макете.
В winforms у вас есть свойство AutoSize
и TableLayoutPanel
/ FlowLayoutPanel
, чтобы легко создавать динамические макеты.
Руководство:
TableLayoutPanel
(2 столбца, 2 строки, установить каждый в Auto
после добавления содержимого), установите [d3], CheckedListBox
es), установите Visibility = False
на изначально скрытые, AutoSize = True
и AutoSizeMode = GrowAndShrink
в форму и TableLayoutPanel
; CheckedChanged
изменение события Visibility
, а остальное происходит автоматически. Давайте посмотрим на ошибки:
blockquote>Variable not in scope: evaluate :: t0 -> Integer -> t Data constructor not in scope: Constant
Это означает, что вы не определили функцию
evaluate
и конструкторConstant
(даже если вы явно есть). Но вы говорите, что когда вы используетеgetValue
иX
, эти работы?Это, как представляется, не является (чрезвычайно распространенной) многострочной
ghci
путаницей, как это предлагается в комментарии. Во-первых, ошибка, которую вы получаете от этого, как правило,non-exhaustive patterns
, а это не то, что вы получаете. Во-вторых, ваша подсказкаghci
читает*Main>
вместоPrelude>
, что означает, что вы:load
отредактировали файл. Указанный файл просто не определил код, который вы ожидаете получить.Я предполагаю, что вы написали первую часть кода в файле, затем
:load
отредактировали его правильно, затем изменили файл и забыли:reload
, поэтому сделанные вами изменения никогда не загружались. [1138 ]Другая возможность состоит в том, что вы поместили
module Main (VariableName (..), getValue) where
в начало вашего файла и забыли добавить в него новый экспорт. Но это кажется менее вероятным.Если ничего из вышеперечисленного не работает, попробуйте закрыть
ghci
, открыть его снова и:load
заново создать файл.
Даже после того, как вы исправите эту проблему, вы столкнетесь с рядом других ошибок, в основном связанных с круглыми скобками. В Haskell, когда вы пишете что-то вроде этого:
evaluate Constant 20
Это означает «вызовите функцию
evaluate
и передайте ей два аргумента:Constant
и20
». Это подразумеваетevaluate :: Expression -> Int -> Int
, но вы действительно хотитеevaluate :: Expression -> Int
. Поэтому вам нужны круглые скобки:evaluate (Constant 20)
Это означает, что «вызовите конструктор
Constant
с одним аргументом20
и передайте это значение в качестве единственного аргументаevaluate
».
Это изменение нужно не только вносить в сайт вызовов, оно также необходимо в определении. В настоящее время у вас есть:
evaluate :: Expression -> Int evaluate Constant x = x evaluate Variable x = getValue x evaluate Add x y = x+y evaluate Multiply x y = x * y
Каждый из этих шаблонов ожидает различное количество аргументов: первые два ожидают два аргумента, а последние два ожидают три аргумента. Проблема в том, что
x
иy
рассматриваются как аргументы функции, а не конструкторы. Чтобы изменить это, вам нужны круглые скобки:evaluate :: Expression -> Int evaluate (Constant x) = x evaluate (Variable x) = getValue x evaluate (Add x y) = x+y evaluate (Multiply x y) = x * y
Последнее изменение, которое вам нужно сделать, - это определение конструктора: вы должны сначала сказать конструкторам, что они принимают аргументы. В настоящее время ваше определение данных выглядит следующим образом (я добавил форматирование):
data Expression = Constant | Variable | Add | Multiply deriving Show
Ни один из этих конструкторов в настоящее время не принимает аргументы: это значения (например,
True
,X
,Nothing
, и т. д.), а не конструкторы значений. Это не то, что вы хотите. Вам нужно указать типы аргументов для каждого конструктора, например:data Expression = Constant Int | Variable VariableName | Add Int Int | Multiply Int Int deriving Show