У меня возникают проблемы с типами при изучении Haskell. У меня есть класс под названием Stack
, который, очевидно, должен вести себя как стек. У меня есть тип Elem
, который просто является Int или Bool.Тип проблемы с пользовательским typeclass
Теперь я хочу, чтобы моя функция принимала Stack
Elem
и выполняла некоторые операции с ней. Результат на самом деле не важен, однако я не могу даже получить первый элемент стека, и я не смог выяснить, что не так в течение нескольких часов.
import Control.Monad
data Elem = Number Int | Truth Bool deriving Eq
instance Show Elem where
show (Number i) = show i
show (Truth b) = show b
class Stack stack where
push :: a -> stack a -> stack a
top :: MonadPlus m => stack a -> m (a,stack a)
empty :: stack a
isEmpty :: stack a -> Bool
instance Stack [] where
push a stack = a:stack
top stack = if isEmpty stack then mzero else return (head stack, tail stack)
empty = []
isEmpty stack = if null stack then True else False
step :: Stack stack => String -> stack Elem -> Maybe (stack Elem)
step ex st = let e1 = top st :: Maybe (Elem, stack Elem)
--a1 = fmap fst e1
--e2 = top (fmap snd e1)
--a2 = fmap fst e2
in Nothing
Ошибка я получаю
Playground.hs:22:27:
Could not deduce (stack ~ stack2)
from the context (Stack stack)
bound by the type signature for
step :: Stack stack => String -> stack Elem -> Maybe (stack Ele
m)
at Playground.hs:21:9-65
`stack' is a rigid type variable bound by
the type signature for
step :: Stack stack => String -> stack Elem -> Maybe (stack Elem
)
at Playground.hs:21:9
`stack2' is a rigid type variable bound by
an expression type signature: Maybe (Elem, stack2 Elem)
at Playground.hs:22:23
Expected type: stack2 Elem
Actual type: stack Elem
Relevant bindings include
st :: stack Elem
(bound at Playground.hs:22:9)
step :: String -> stack Elem -> Maybe (stack Elem)
(bound at Playground.hs:22:1)
In the first argument of `top', namely `st'
In the expression: top st :: Maybe (Elem, stack Elem)
Я действительно не понимаю, почему Haskell отказывается это (и даже отказывается просто называя top st
в моей функции без меня, пытаясь определить тип).
Я надеюсь, что кто-то может пролить свет на это!
Компилятор не знает, что 'stack' в типе sig' step' - это тот же 'stack' в' Maybe (Elem, stack Elem) '. Вы ищете 'ScopedTypeVariables', но это означает, что вам нужно будет изменить sig на' step :: forall stack. Stack stack => String -> stack Elem -> Maybe (stack Elem) '. – bheklilr
@bheklilr У меня нет доступа к синтаксису forall. Должно быть возможно каким-то образом получить первый элемент стека в моей функции ?! – Marco
Вы положили '{- # LANGUAGE ScopedTypeVariables # -}' вверху вашего файла? – bheklilr