Как правильно квалифицировать типы для работы со случайными монадами

Я хочу создать структуру данных, состоящую из определенных функций на основе: сгиба, логических операций, числовых операций (арифметических и сравнений) и основных строковых операций. Я буду пытаться развивать этот класс функций. Здесь я получаю сообщение об ошибке с MonadRandom.

Вот мой код:

-- The following language extensions need to be enabled:
-- DeriveDataTypeable, FlexibleInstances, MultiParamTypeClasses

{-# LANGUAGE FlexibleContexts, DeriveDataTypeable, FlexibleInstances, MultiParamTypeClasses, StandaloneDeriving, ExistentialQuantification , GADTs #-}
{-# LANGUAGE RankNTypes #-}

import GenProg
import GenProg.GenExpr
import GenProg.GenExpr.Data
import Data.Generics
import Control.Monad
import Control.Monad.Random
import Data.Fixed
import Data.Typeable
import Data.Data

class IsGenExp t where
      mutate :: (MonadRandom m) => t -> m t
      crossOver :: (MonadRandom m) => t -> t -> m t
      randomGen :: (MonadRandom m) => m t

data GenExp = forall t . IsGenExp t => GenExp t

data IntExp = IntExp Int
data FloatExp = FloatExp Float
data ListExp = ListExp [GenExp]
data ArithExp = Add GenExp GenExp | Sub GenExp GenExp | Mul GenExp GenExp
data CompExp = Eq GenExp GenExp | Lt GenExp GenExp | Gt GenExp GenExp

instance IsGenExp IntExp where
 --  randomGen = (getRandomR (IntExp 1,IntExp 3))
   randomGen = do
    r <- getRandomR (0, 100)
    return r

И ошибка, которую я получаю:

GADT.hs:33:10:
    Could not deduce (Random IntExp) arising from a use of `getRandomR'
    from the context (MonadRandom m)
      bound by the type signature for
                 randomGen :: MonadRandom m => m IntExp
      at GADT.hs:32:4-12
    In a stmt of a 'do' block: r <- getRandomR (0, 100)
    In the expression:
      do { r <- getRandomR (0, 100);
           return r }
    In an equation for `randomGen':
        randomGen
          = do { r <- getRandomR (0, 100);
                 return r }

GADT.hs:33:22:
    Could not deduce (Num IntExp) arising from the literal `0'
    from the context (MonadRandom m)
      bound by the type signature for
                 randomGen :: MonadRandom m => m IntExp
      at GADT.hs:32:4-12
    In the expression: 0
    In the first argument of `getRandomR', namely `(0, 100)'
    In a stmt of a 'do' block: r <- getRandomR (0, 100)
Failed, modules loaded: none.

Как это исправить?


person Kaivan Shah    schedule 11.07.2015    source источник


Ответы (1)


Пытаться:

instance IsGenExp IntExp where
   randomGen = do
    r <- getRandomR (0, 100)
    return $ IntExp r

Примечание:

  • r это число
  • IntExp r is an IntExp
  • return $ IntExp r является m IntExp для монадного типа m
person ErikR    schedule 11.07.2015
comment
Спасибо. Это сработало! :) IntExp похож на обертку, верно? - person Kaivan Shah; 14.07.2015
comment
В некотором смысле. Это способ построения IntExp из Int. - person ErikR; 14.07.2015
comment
Ах понятно. Совсем другой вопрос, если вы можете мне помочь. Я получаю сообщение об ошибке, когда делаю свой 'data Expr' экземпляром Data. Код и ошибка: lpaste.net/136444. - person Kaivan Shah; 15.07.2015
comment
Как насчет того, чтобы просто: deriving instance Typeable (Expr) — вам это помогло? - person ErikR; 15.07.2015
comment
Ошибка относительно экземпляра данных все еще существует. Я обновил ту же самую lpaste, и вы можете взглянуть на нее. Когда я спросил в irc, они сказали, что GADT не должны работать с данными. Если возможно, потребуется выполнить некоторую переработку с классом данных. - person Kaivan Shah; 15.07.2015