无法从上下文中推断出[...] - 是否有可能避免显式约束?

时间:2016-09-20 13:18:53

标签: haskell

鉴于下面的代码(可在线修改和编译here),编译会出现此错误:

  

无法从上下文中使用'solveFormulaPart'推断出(Num a1):

     

StateGettable IdState a

     

由类型签名绑定:

     

solveFormula :: StateGettable IdState a => IdState - > StateFormula1一个StateMonad IdState a

     

可能的解决方法:将(Num a1)添加到数据构造函数“StateFormula1”的上下文中

是否有任何解决方案可以消除必须明确赋予StateFormula1StateFormulaPart数据构造函数的所有约束的必要性? (理想情况下,同一个StateFormula实例应该可以与任何State实例一起重复使用,只要底层类型看起来与使用站点所需的约束相匹配)

{-# LANGUAGE ConstraintKinds        #-}
{-# LANGUAGE FlexibleContexts       #-}
{-# LANGUAGE FlexibleInstances      #-}
{-# LANGUAGE GADTs                  #-}
{-# LANGUAGE InstanceSigs           #-}
{-# LANGUAGE MultiParamTypeClasses  #-}
{-# LANGUAGE TypeFamilies           #-}


import           Control.Monad.Trans.Maybe
import           Control.Monad.IO.Class
import           Control.Monad.Trans.Class
import           GHC.Exts (Constraint)

data StateFormulaPart a where
    Constant :: a -> StateFormulaPart a
    Property :: (StateProperty a) -> StateFormulaPart a


type SFP a = StateFormulaPart a


data StateFormula1 b where
    StateFormula1 :: SFP a
                  -> (a -> b)
                  -> StateFormula1 b


class StateFormula formula where
    -- todo remove this if the kind can be inferred using another method
    explicitKind :: formula a -> formula a


instance StateFormula StateFormula1


data StateProperty a =
    StateProperty { propertyKey     :: String
                  , propertyDefault ::  a
                  }


class Monad (StateMonad state) => State state where
    type StateMonad state :: * -> *
    type StateGettable state :: * -> Constraint
    getPropertyValue :: StateGettable state a => state -> StateProperty a -> StateMonad state a


class (StateFormula formula, State state) => StateSolver state formula where
    solveFormula :: StateGettable state a => state -> (formula a) -> StateMonad state a
    solveFormulaPart :: StateGettable state a => state -> (SFP a) -> StateMonad state a


data IdState = IdState


instance State IdState where
    type StateMonad IdState = MaybeT IO
    type StateGettable IdState = Num


instance StateSolver IdState StateFormula1 where
    -- solveFormulaPart :: Num a => IdState -> SFP a -> MaybeT IO a
    solveFormulaPart s (Constant x) = return x
    solveFormulaPart s (Property p) = do
        liftIO $ print (propertyKey p)
        return (propertyDefault p)

    -- solveFormula :: Num a => IdState -> StateFormula1 a -> MaybeT IO a
    solveFormula s (StateFormula1 p1 f) = do
        x1 <- solveFormulaPart s p1
        return $ f x1


workingFormula :: StateFormula1 Int
workingFormula = StateFormula1 (Property $ StateProperty "test" 5 :: StateFormulaPart Int) id


main = runMaybeT $ solveFormula IdState workingFormula

0 个答案:

没有答案