2015-10-13 2 views
0

В настоящее время я пишу компилятор в Haskell как игрушка проект и у меня есть функция, которая выполняет динамическую трансформацию с подписью:Transform функции без гражданства, чтобы Stateful один

transform :: (Exp -> m Exp) -> Exp -> m Exp 

Это позволяет мне реализовать следующие типы операций над ним:

  • Результаты накопления, например получить список функций, вызываемых внутри выражения.
  • Преобразования, которые могут возвращать ошибки, например. который либо возвращает AST с типами, либо с ошибкой, описывающей проблемы типа.
  • преобразования, которые зависят от ранее сделанных преобразований, например. дедупликация имен переменных при генерации тестового ввода.
  • Я надеюсь, что это также позволит мне делать вычисления без учета состояния без изъятия.

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

map :: (Exp -> Exp) -> Exp -> Exp 

Я предпочел бы не имеют одинаковую логику о том, как снова пересекать детей на карте, но на самом деле реализовать ее поверх преобразования.

+2

Что такое 'm' в вашем методе' transform'? Это произвольная монада? Не могли бы вы использовать монаду «Идентичность»? –

+0

Если вы действительно имеете в виду 'transform :: Monad m => (Exp -> m Exp) -> Exp -> m Exp', то вы можете создать экземпляр' m' с 'Identity' и получить свою« карту ». – user2407038

+0

Да, m - произвольная монада, поэтому я могу выбрать ее для реализации функции отображения. Но как именно я это сделал? Извините, это, вероятно, очень очевидно, но я как-то смущен, потому что я, вероятно, слишком долго думал об этом. – Lykos

ответ

4

Если это фактический тип transform, то вы должны быть в состоянии сделать что-то вроде этого:

Control.Monad.Identity> :t transform 
transform :: (Exp -> m Exp) -> Exp -> m Exp 
Control.Monad.Identity> :t \f -> runIdentity . transform (Identity . f) 
\f -> runIdentity . transform (Identity . f) 
    :: (Exp -> Exp) -> Exp -> Exp 

Однако, вполне возможно, что у вас есть другие ограничения на m, что вы не написали, в вопрос, который может исключить Identity.

+0

Нет, ограничений на m нет. В конце концов, я написал свою операцию преобразования таким образом, чтобы поддерживать разные типы монад. Большое спасибо. Ключевой частью, которую я не видел, было то, как «вытащить» ее из монады. Но runIdentity решает это, поэтому спасибо за это! – Lykos

Смежные вопросы