Dzięki Odpowiedź Ptharien's Flame (proszę, upvote it!) Udało mi się zaadaptować przykładową monadę z "Learn You a Haskell for a Great Good". Ponieważ musiałem google trochę szczegółów (bycie nowicjuszem Haskella) tutaj jest to, co zrobiłem na końcu (przykład flipThree w "Learn ..." daje teraz [(True, 9% 40), (Fałsz, 31% 40)]):
plik sterowania/Restricted.hs (skrócić go usunąłem RApplicative, RMonadPlus etc):
{-# LANGUAGE ConstraintKinds, TypeFamilies, KindSignatures, FlexibleContexts, UndecidableInstances #-}
module Control.Restricted (RFunctor(..),
RMonad(..)) where
import Prelude hiding (Functor(..), Monad(..))
import Data.Foldable (Foldable(foldMap))
import Data.Monoid
import GHC.Exts (Constraint)
class RFunctor f where
type Restriction f a :: Constraint
fmap :: (Restriction f a, Restriction f b) => (a -> b) -> f a -> f b
class (RFunctor m) => RMonad m where
return :: (Restriction m a) => a -> m a
(>>=) :: (Restriction m a, Restriction m b) => m a -> (a -> m b) -> m b
(>>) :: (Restriction m a, Restriction m b) => m a -> m b -> m b
a >> b = a >>= \_ -> b
join :: (Restriction m a, Restriction m (m a)) => m (m a) -> m a
join a = a >>= id
fail :: (Restriction m a) => String -> m a
fail = error
plików Prob.hs:
{-# LANGUAGE ConstraintKinds, TypeFamilies, RebindableSyntax, FlexibleContexts #-}
import Data.Ratio
import Control.Restricted
import Prelude hiding (Functor(..), Monad(..))
import Control.Arrow (first, second)
import Data.List (all)
newtype Prob a = Prob { getProb :: [(a, Rational)] } deriving Show
instance RFunctor Prob where
type Restriction Prob a = (Eq a)
fmap f (Prob as) = Prob $ map (first f) as
flatten :: Prob (Prob a) -> Prob a
flatten (Prob xs) = Prob $ concat $ map multAll xs
where multAll (Prob innerxs, p) = map (\(x, r) -> (x, p*r)) innerxs
compress :: Eq a => Prob a -> Prob a
compress (Prob as) = Prob $ foldr f [] as
where f a [] = [a]
f (a, p) ((b, q):bs) | a == b = (a, p+q):bs
| otherwise = (b, q):f (a, p) bs
instance Eq a => Eq (Prob a) where
(==) (Prob as) (Prob bs) = all (`elem` bs) as
instance RMonad Prob where
return x = Prob [(x, 1%1)]
m >>= f = compress $ flatten (fmap f m)
fail _ = Prob []
Dzięki za szybką odpowiedź. Muszę o tym trochę pomyśleć (przed zaakceptowaniem). –
Okazuje się, że ktoś nareszcie wprowadził "standardową" implementację ograniczonych wersji klas kategorii na Hackage] (http://hackage.haskell.org/package/ConstraintKinds), choć nie wydaje się to jeszcze kompletne (szczególnie brak 'Monad' ...) ([wersja rozwojowa już to ma] (https://github.com/mikeizbicki/ConstraintKinds/blob/master/src/Control/ConstraintKinds/Monad.hs)) – leftaroundabout
Po prostu udało mi się skompiluj swój kod pod GHC 7.4.2. W tym celu musiałem dodać "gdzie" na końcu linii zaczynając od "instancji", "m" przed b na końcu linii zaczynając od (>>), wiersz "import GHC.Prim (ograniczenie) "i dodaj funkcję językową" UndecidableInstances ". Dalej próbuję go użyć ... –