Продолжайте получать (используйте FlexibleContexts, чтобы разрешить это) Ошибка в простой функции Haskell

Я просто играю с монадами на Haskell и получаю сообщение об ошибке, которое не могу исправить. Мой сегмент кода использует состояние Monad, чтобы сложить вместе первые два символа из строки и вернуть их как часть состояния. Моя строка "put" продолжает давать мне ошибку:

* Non type-variable argument in the constraint: MonadState [a] m
  (Use FlexibleContexts to permit this)
* When checking the inferred type
    testH :: forall (m :: * -> *) a. MonadState [a] m => [a] -> m [a]

Как я могу это исправить? Расширение языка не вариант, мне просто нужно знать, как я могу изменить свой код, чтобы заставить его работать

test xs = 
 runState (testH (tail xs)) ((head xs):[])

testH xs =
 do
  a <- get 
  put ((head xs):a)
  b <- get
  return b

1 ответ

Вы можете решить эту проблему, включив FlexibleContexts как это предлагается, или путем изменения вашей функции, чтобы работать на что-то более общее, чем списки.

Проблема в том, что Haskell не допускает переменные не-типа в контексте. Если вы напишите типы ваших функций (которые вы должны делать в любом случае), вы получите

testH :: (Monad m,MonadState [a] m) => [a] -> m [a]

это означает, что это функция, которая принимает список значений и возвращает действие в некоторой монаде, которая имеет возможность сохранять состояние списка значений того же типа, что и входные данные. К сожалению, [a] бит в контексте недопустим в Haskell, потому что он имеет переменную не типового типа (а именно конструктор типа списка).

Лучшее решение здесь - просто включить расширение, которое допускает не типизированные переменные в контекстах. Это не опасно, просто расслабляет стандарт. На самом деле, многопараметрические классы типов (такие как MonadState) не действительны на Haskell, поэтому вы уже используете языковые расширения, нравится вам это или нет.

Если это действительно не вариант, вы можете изменить его на (Monad m,SomeTypeclass f,MonadState (f a) m)и переписать ваши функции для работы с любым конструктором, который следует за SomeTypeclass на ваш выбор. Это удаляет конструктор типа списка из типа и позволяет коду работать без FlexibleContexts,

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