больше библиотек rmonad? - PullRequest
       7

больше библиотек rmonad?

4 голосов
/ 08 сентября 2011

Я хочу сделать несколько элементарных вещей с RMonad.Существуют ли способы использовать функциональность «как монаду» для

  • с идентификатором rmonad, для применения монадных трансформаторов к?
  • есть общие вещи, такие как StateT трансформаторы?
  • добавить ограничение к существующей монаде?(например, если бы кто-то хотел StateT с дополнительными ограничениями)

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

edit

Я взломал StateT вместе из библиотечных источников, посмотрю, работает ли он ...

[http://pastebin.com/VT3uyEgr]

1 Ответ

4 голосов
/ 08 сентября 2011

Ваша версия StateT выглядит правильно после быстрого взгляда. К сожалению, используя RMonad et. и др. требует дублирования почти всего; Я начал писать некоторый код с использованием «Подходящего» и сдался, потому что в нем было слишком много дублирования (и, в конце концов, оно мне действительно не понадобилось).

Edit:

Из моей памяти о том, как Suitable работает, это примерно так:

Рассмотрим класс Functor: Set не может быть его экземпляром, так как ему требуется дополнительное ограничение Ord.

Наивный подход будет выглядеть примерно так:

{-# LANGUAGE UndecidableInstances #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE FunctionalDependencies #-}
{-# LANGUAGE MultiParamTypeClasses #-}

import qualified Data.Set as S

class MyFunctor c a | c -> a where
      myfmap :: (MyFunctor c b) => (a -> b) -> c a -> c b

instance (Ord a) => MyFunctor S.Set a where
      myfmap = S.map

Но тогда возвращается следующая ошибка:

Error: test.hs:11:16: Could not deduce (Ord b) arising from a use of `S.map'
    from the context (Ord a)
      bound by the instance declaration at /tmp/test.hs:10:10-37
    or from (MyFunctor S.Set b)
      bound by the type signature for
                 myfmap :: MyFunctor S.Set b => (a -> b) -> S.Set a -> S.Set b
      at /tmp/test.hs:11:7-20
    Possible fix:
      add (Ord b) to the context of
        the type signature for
          myfmap :: MyFunctor S.Set b => (a -> b) -> S.Set a -> S.Set b
        or the instance declaration
    In the expression: S.map
    In an equation for `myfmap': myfmap = S.map
    In the instance declaration for `MyFunctor S.Set a'

Почему это? Это потому, что ограничение не сохраняется или не обнаруживается на уровне экземпляра, поэтому GHC не осознает, что при использовании myfmap должно быть ограничение Ord на b.

Тип Suitable используется для явного создания словаря ограничений, который позволяет указывать следующие виды ограничений:

import Data.Suitable
import qualified Data.Set as S

class MyFunctor c where
      myfmap :: (Suitable c a, Suitable c b) => (a -> b) -> c a -> c b

instance MyFunctor S.Set where
      myfmap f s = withConstraintsOf s
                   $ \ SetConstraints
                       -> withResConstraints $ \ SetConstraints -> S.map f s

(где SetConstraints уже определено в Data.Suitable)

Эта реализация работает, но она делает сигнатуры типов немного более замысловатыми, а реализации методов - немного более выразительными (обратите внимание, здесь нам нужно ввести SetConstraints дважды : один раз для Set a другой для Set b). Обратите внимание, что для типов без каких-либо ограничений ни одна из функций ограничения Suitable не требуется.

Я начал пытаться создавать Suitable версии классов в Typeclassopedia, но сдался, потому что экземпляры становились довольно волосатыми.

...