Вы получаете это сообщение об ошибке, потому что нет экземпляра SymVal для SBool
, только для Bool
, а S.length
ожидает значения S.SList
из SymVal
:
length :: SymVal a => SList a -> SInteger
Это можно исправить, изменив toNum
и isValid
для принятия y S.SList Bool
и изменив тип xs
на S.SList Bool
:
help :: S.SymbolicT IO ()
help = do
xs :: S.SList Bool <- S.sList "xs"
S.constrain $ isValid xs
S.minimize "goal" $ toNum xs
isValid :: S.SList Bool -> S.SBool
isValid xs =
Sl.length xs S..> 0
toNum :: S.SList Bool -> S.SInteger
toNum xs =
Sl.length xs
Ваши функции isValid
и toNum
также чрезмерно специализированы, поскольку для них требуется только ограничение класса SymVal
. Следующее является более общим и все еще компилируется:
isValid :: S.SymVal a => S.SList a -> S.SBool
toNum :: S.SymVal a => S.SList a -> S.SInteger
РЕДАКТИРОВАТЬ
Если бы toNum
не провела проверку типов, вы бы также увидели, что S.sList
также не выполняет проверку типов, поскольку его сигнатура типа имеет ограничение SymVal
на параметр типа возвращаемых S.SList
:
sList :: SymVal a => String -> Symbolic (SList a)
Удаление isValid
и toNum
и сохранение только конструктор S.sList
:
help = do
xs :: S.SList S.SBool <- S.sList "xs"
return ()
выдает эту ошибку:
• No instance for (S.SymVal S.SBool)
arising from a use of ‘S.sList’
Что, на мой взгляд, говорит немного больше о фактической проблеме. Это просто говорит о том, что минимальный пример иногда может быть еще более минимальным и, следовательно, более полезным.