2014-09-08 2 views
1

Я ожидаю, что функция noToState ниже работает, которая перемещается между всеми состояниями, чтобы найти ту, которая соответствует указанному номеру состояния и возвращает состояние.Как определить функцию, возвращающую полиморфное значение

class State a where 
    allStates :: [a] 

class (State a) => IntState a where 
-- starting from zero, consecutive             
    stateNo :: a -> Integer 

noToState :: (IntState a) => Integer -> a 
noToState n = case lookup n $ zip (map stateNo allStates) allStates of 
    Just st -> st 
    Nothing -> undefined -- this should never happen 

Однако он дает ошибку: Could not deduce (IntState a0) arising from a use of ‘stateNo’.

Так в коде, где я совершил ошибки? Как мне их исправить? Благодарю.

+0

Подобно тому, как замечание: то, что вы пытаетесь сделать? Может быть, вам действительно не нужны типы классов (или ваши собственные) вообще – Carsten

+0

@ CarstenKönig Я определяю алгоритм k-path для преобразования DFA в регулярное выражение. Так что мне нужен способ получить доступ к состоянию с цифрами :) –

+0

ok - но я предполагаю, что у вас есть конкретное представление вашего DFA/State, так почему бы просто не сделать эту функцию для этого представления? Ну, неважно, я надеюсь, что мой ответ поможет вам (и работе) – Carsten

ответ

4

Изменить его на что-то вроде этого:

noToState :: (IntState a) => Integer -> a 
noToState n = case lookup n $ zip (map stateNo allSts) allSts of 
    Just st -> st 
    Nothing -> undefined -- this should never happen 
    where allSts = allStates 

Проблема заключается в том, что вы используете allStates дважды, и это может быть разные вещи

+0

Круто, это помогает! Фактически '(State a)' здесь избыточно, поскольку это подразумевается определением класса 'IntState', и его можно удалить безопасно :) –

+0

Да, как-то это испортило;) – Carsten

+0

Обратите внимание, что это зависит от мономорфизма ограничение: если вы отключите это, 'allSts' будет набираться с полным полиморфным типом' allStates', что снова приведет к ошибке предыдущего типа. Лично я использовал бы 'ScopedTypeVariables' вместо этого для оценки' allStates' по заданному типу. Это вопрос личного предпочтения. – chi