鉴于下面的代码(可在线修改和编译here),编译会出现此错误:
无法从上下文中使用'solveFormulaPart'推断出(Num a1):
StateGettable IdState a
由类型签名绑定:
solveFormula :: StateGettable IdState a => IdState - > StateFormula1一个StateMonad IdState a
可能的解决方法:将(Num a1)添加到数据构造函数“StateFormula1”的上下文中
是否有任何解决方案可以消除必须明确赋予StateFormula1
和StateFormulaPart
数据构造函数的所有约束的必要性? (理想情况下,同一个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