Скажите, пожалуйста, в чем проблема?
data Stack' v = Stack' [v] Int deriving (Show) ... type StackInt = Stack' Int main = print(StackInt [1,2,3] 4)
Ошибка, которую я получаю,
Not in scope: data constructor `Stackint'
Что не так?
Скажите, пожалуйста, в чем проблема?
data Stack' v = Stack' [v] Int deriving (Show) ... type StackInt = Stack' Int main = print(StackInt [1,2,3] 4)
Ошибка, которую я получаю,
Not in scope: data constructor `Stackint'
Что не так?
Мне кажется, что вы путаете понятия типов и конструкторов, это общая проблема, поскольку они живут в отдельных пространствах имен и часто получают одно и то же имя. В выражении Haskell
data SomeType = SomeType Int
скажем, вы фактически определяете тип SomeType
и конструктор SomeType
. Тип не является функцией в обычном смысле, но конструктор. Если вы спросите ghci о типе SomeType, вы получите следующее:
:t SomeType
SomeType :: Int -> SomeType
Теперь объявление type
является просто сокращением для более длинного определения типа, в вашем случае делая StackInt
синонимом Stack' Int
. Но для построения значения этого типа вам все равно нужно использовать конструктор Stack'
(который имеет тип [v] -> Int -> Stack' v
). Таким образом, ваш код должен быть
data Stack' v = Stack' [v] Int deriving (Show)
main = print(Stack' [1,2,3] 4)
Если вы хотите убедиться, что тип был Stack' Int
, вы можете добавить функцию
data Stack' v = Stack' [v] Int deriving (Show)
stackInt :: [Int] -> Int -> Stack' Int
stackInt list i = Stack' list i
main = print(stackInt [1,2,3] 4)
EDIT: Я также не написал stackInt list i = Stack' list i
для прозрачности здесь, но вы можете написать его более элегантно, как stackInt = Stack'
. Это ограничение типа, которое гарантирует, что вы получите правильный тип здесь.
Вы могли бы также иметь как новую функцию, так и синоним типа, если хотите, т.е.
data Stack' v = Stack' [v] Int deriving (Show)
type StackInt = Stack' Int
stackInt :: [Int] -> Int -> StackInt
stackInt list i = Stack' list i
main = print(stackInt [1,2,3] 4)
Имя конструктора Stack'
, а не StackInt
. Создание псевдонима типа с помощью type
не создает псевдоним для конструкторов (что не имеет смысла, поскольку для типа может быть много конструкторов, и их имена не обязательно должны быть связаны с именем типа вообще).
Нет конструктора данных Stackint
. Stackint
, как определено вашим объявлением type
, является конструктором типа.
Конструктор данных, как и для Stack'
, Stack'
, хотя благодаря синониму типа он будет иметь тип Int -> Stack' Int
вместо a -> Stack' a
.